package ee.ajapaik.android.fragment;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import ee.ajapaik.android.external.bitmaputil.ImageFetcher;
import ee.ajapaik.android.external.touch.TouchImageView;
import ee.ajapaik.android.CameraActivity;
import ee.ajapaik.android.ConfirmActivity;
import ee.ajapaik.android.R;
import ee.ajapaik.android.camera.CameraPreview;
import ee.ajapaik.android.loader.BitmapLoader;
public class CameraFragment extends Fragment implements Camera.ShutterCallback, Camera.PictureCallback, LoaderCallbacks<Bitmap> {
public static String TAG = "CameraFragment";
private Camera camera;
private FrameLayout previewSurfaceContainer;
private SimpleDateFormat format;
private boolean containerLand = true;
private boolean rotated = false;
private ImageFetcher imageFetcher;
public static Fragment newInstance() {
return new CameraFragment();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
format = new SimpleDateFormat();
format.applyPattern("ddMM_kkmmss");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup vg, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.camera, null);
previewSurfaceContainer = (FrameLayout) v.findViewById(R.id.cameraPreview);
v.findViewById(R.id.photoButton).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (camera == null) {
return;
}
camera.takePicture(CameraFragment.this, null, CameraFragment.this);
}
});
return v;
}
@Override
public void onResume() {
super.onResume();
camera = Camera.open();
if (camera == null) {
return;
}
Camera.Parameters params = camera.getParameters();
params.setJpegQuality(90);
Log.d(TAG, "imageFormat=" + params.getPictureFormat());
for (Camera.Size sz : params.getSupportedPictureSizes()) {
Camera.Size currentSz = params.getPictureSize();
float ratio = (float)(currentSz.width) / (float)(currentSz.height);
if (sz.height * sz.width > currentSz.height * currentSz.width) {
if (Math.abs(ratio - 1.333f) < 0.01f || Math.abs(ratio - 0.75f) < 0.01f) {
params.setPictureSize(sz.width, sz.height);
}
}
}
Log.d(TAG, "Settled for " + params.getPictureSize().width + "x" + params.getPictureSize().height);
if (params.getPictureFormat() != ImageFormat.JPEG) {
for (int i : params.getSupportedPictureFormats()) {
Log.d(TAG, "supportedImageFormat=" + i);
// try to fall back to JPEG
if (i == ImageFormat.JPEG) {
params.setPictureFormat(ImageFormat.JPEG);
break;
}
}
}
camera.setParameters(params);
setCameraDisplayOrientation(getActivity(), 0, camera);
CameraPreview prev = new CameraPreview(getActivity(), camera);
// int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
TouchImageView tiv = (TouchImageView) getView().findViewById(R.id.tiv);
// System.out.println("rotation=" + rotation + " width=" + width + " height=" + height);
if (width < height) {
// port
prev.setLayoutParams(new FrameLayout.LayoutParams(width, (int)(1.333f * width)));
tiv.setLayoutParams(new FrameLayout.LayoutParams(width, (int)(1.333f * width)));
imageFetcher = new ImageFetcher(getActivity(), width, (int)(1.333f * width), true);
} else {
// land
prev.setLayoutParams(new FrameLayout.LayoutParams((int)(1.333f * height), height));
tiv.setLayoutParams(new FrameLayout.LayoutParams((int)(1.333f * height), height));
imageFetcher = new ImageFetcher(getActivity(), (int)(1.333f * height), height, true);
}
final int id = getActivity().getIntent().getIntExtra(CameraActivity.EXTRA_ID, -1);
getLoaderManager().initLoader(0, BitmapLoader.args(id, width > height), this);
containerLand = width > height;
previewSurfaceContainer.addView(prev);
}
private static Bitmap rotate(Bitmap bmp, float f) {
Matrix mat = new Matrix();
mat.preRotate(90.0f);
return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), mat, false);
}
@Override
public void onPause() {
super.onPause();
if (camera == null) {
return;
}
camera.stopPreview();
previewSurfaceContainer.removeAllViews();
camera.release();
}
public static void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
@Override
public void onPictureTaken(byte[] data, Camera camera) {
String filename = format.format(new Date());
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + "ajapaik");
if (f.exists()) {
Log.w(TAG, "Going to overwrite picture at " + filename);
}
f.mkdirs();
FileOutputStream fos = null;
String filePath = f.getAbsolutePath() + File.separator + filename + ".jpg";
try {
fos = new FileOutputStream(filePath);
fos.write(data);
Log.d(TAG, "Image written to " + filePath);
if (!rotated) {
// we need to rotate the port pics
Bitmap bmp = BitmapFactory.decodeFile(filePath);
bmp = rotate(bmp, 90.0f);
fos = new FileOutputStream(filePath);
bmp.compress(Bitmap.CompressFormat.JPEG, 90, fos);
bmp.recycle();
}
} catch (Exception e) {
Log.w(TAG, "Saving file failed :(");
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ioe) {}
}
}
TouchImageView tiv = (TouchImageView) getView().findViewById(R.id.tiv);
// tiv.get
ConfirmActivity.start(getActivity(), getActivity().getIntent().getIntExtra(CameraActivity.EXTRA_ID, -1), filePath, tiv.getScaleFactor());
}
@Override
public void onShutter() {
// make the shutter sound
}
@Override
public Loader<Bitmap> onCreateLoader(int arg0, Bundle arg1) {
return BitmapLoader.newInstance(getActivity(), arg1);
}
@Override
public void onLoadFinished(Loader<Bitmap> arg0, Bitmap bmp) {
if (bmp == null) {
return;
}
rotated = (containerLand ^ (bmp.getHeight() < bmp.getWidth()));
if (rotated) {
bmp = rotate(bmp, 90.0f);
}
TouchImageView tiv = (TouchImageView) getView().findViewById(R.id.tiv);
if (tiv != null) {
tiv.setImageBitmap(bmp);
}
ImageView photoButton = (ImageView) getView().findViewById(R.id.photoButton);
photoButton.setImageResource(rotated ? R.drawable.btn_camera_rotated : R.drawable.btn_camera);
}
@Override
public void onLoaderReset(Loader<Bitmap> arg0) {
// TODO Auto-generated method stub
}
}