9
0
mirror of https://gitee.com/shuto/customCamera.git synced 2026-05-02 00:07:24 +08:00

Improve the plugin to try/catch outofmemory when we try to rotate or compress a picture.

This commit is contained in:
Christophe BOUCAUT
2015-06-24 16:28:36 +02:00
parent 04677cd5e5
commit 1004a6ea90
7 changed files with 306 additions and 261 deletions
+11 -12
View File
@@ -7,18 +7,10 @@ import android.util.Base64;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;
public class CameraLauncher extends CordovaPlugin {
protected CallbackContext callbackContext;
@@ -57,7 +49,8 @@ public class CameraLauncher extends CordovaPlugin {
return false;
}
TransferBigData.setImgBackgroundBase64(imgBackgroundBase64);
TmpFileUtils.createTmpFile(this.cordova.getActivity(), CameraActivity.NAME_FILE_BACKGROUND, imgBackgroundBase64);
imgBackgroundBase64 = null;
}
if (args.getString(1) != "null") {
@@ -71,11 +64,12 @@ public class CameraLauncher extends CordovaPlugin {
return false;
}
TransferBigData.setImgBackgroundBase64OtherOrientation(imgBackgroundBase64OtherOrientation);
TmpFileUtils.createTmpFile(this.cordova.getActivity(), CameraActivity.NAME_FILE_BACKGROUND_OTHER, imgBackgroundBase64OtherOrientation);
imgBackgroundBase64OtherOrientation = null;
}
// If we don't have a background image, disable miniature and opacity options.
if (TransferBigData.getImgBackgroundBase64() == null) {
if (args.getString(0) == "null") {
intent.putExtra("miniature", false);
intent.putExtra("opacity", false);
} else {
@@ -113,6 +107,9 @@ public class CameraLauncher extends CordovaPlugin {
* @param intent Contains parameters of the activity.
*/
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
// remove temporary files.
this.cordova.getActivity().deleteFile(CameraActivity.NAME_FILE_BACKGROUND);
this.cordova.getActivity().deleteFile(CameraActivity.NAME_FILE_BACKGROUND_OTHER);
if (requestCode == CameraLauncher.REQUEST_CODE) {
switch (resultCode) {
case CameraLauncher.RESULT_ERROR:
@@ -125,9 +122,11 @@ public class CameraLauncher extends CordovaPlugin {
break;
case CameraLauncher.RESULT_SUCCESS:
try {
byte[] output = Base64.encode(TransferBigData.getImgTaken(),
byte[] output = Base64.encode(TmpFileUtils.getTmpFileContent(this.cordova.getActivity(), CameraActivity.NAME_FILE_PICTURE_TAKEN),
Base64.NO_WRAP);
this.cordova.getActivity().deleteFile(CameraActivity.NAME_FILE_PICTURE_TAKEN);
String jsOut = new String(output);
output = null;
this.callbackContext.success(jsOut);
} catch (Exception e) {
@@ -17,8 +17,8 @@
<ImageView
android:id="@+id/background"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.2"
android:scaleType="fitXY" />
@@ -1,8 +1,11 @@
package org.geneanet.customcamera;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.util.DisplayMetrics;
import android.view.Display;
public class BitmapUtils {
/**
@@ -19,48 +22,49 @@ public class BitmapUtils {
return options;
}
/**
* Determine the best value of inSampleSize in the option object to adapt the picture at the screen size.
*
* @param Options options Option object to set inSampleSize.
* @param int destWidth Width destination.
* @param int destHeight Height destination.
*/
public static void determineInSampleSize(Options options, int destWidth, int destHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > destHeight || width > destWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
// More informations: http://developer.android.com/training/displaying-bitmaps/load-bitmap.html#load-bitmap
while ((halfHeight / inSampleSize) > destHeight
&& (halfWidth / inSampleSize) > destWidth) {
inSampleSize *= 2;
}
}
options.inSampleSize = inSampleSize;
}
/**
* Decode a byte array to generate a base64 adapted at the destination's size.
* Generate a bitmap optimized from the screen sizes.
*
* @param bytes[] imgBackgroundBase64
* @param Options options
* @param activity Current activity.
* @param data Bytes represent the picture.
*
* @return Bitmap
*/
public static Bitmap decodeOptimalPictureFromByteArray(byte[] imgBackgroundBase64, Options options) {
public static Bitmap generateOptimizeBitmap(Activity activity, byte[] data) {
// Get sizes screen.
Display defaultDisplay = activity.getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
defaultDisplay.getMetrics(displayMetrics);
int displayWidthPx = (int) displayMetrics.widthPixels;
int displayHeightPx = (int) displayMetrics.heightPixels;
// Get picture.
Options options = BitmapUtils.determineOriginalSizePicture(data);
int widthResize = 0;
int heightResize = 0;
int widthBackground = options.outWidth;
int heightBackground= options.outHeight;
float ratioX = (float) widthBackground / (float) displayWidthPx;
float ratioY = (float) heightBackground / (float) displayHeightPx;
int inSampleSize = 1;
if (ratioX > ratioY && ratioX > 1) {
widthResize = (int) displayWidthPx;
heightResize = (int) (heightBackground / ratioX);
inSampleSize = (int) ratioX;
} else if (ratioX <= ratioY && ratioY > 1) {
widthResize = (int) (widthBackground / ratioY);
heightResize = (int) displayHeightPx;
inSampleSize = (int) ratioY;
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(imgBackgroundBase64, 0, imgBackgroundBase64.length, options);
Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length, options);
data = null;
if (widthResize > 0 && heightResize > 0) {
picture = Bitmap.createScaledBitmap(picture, widthResize, heightResize, true);
}
return picture;
}
}
@@ -9,7 +9,6 @@ import android.content.res.Resources.NotFoundException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
@@ -19,15 +18,14 @@ import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.StateListDrawable;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.Surface;
@@ -46,11 +44,14 @@ import android.widget.TextView;
import org.geneanet.customcamera.CameraPreview;
import org.geneanet.customcamera.ManagerCamera;
import org.geneanet.customcamera.TransferBigData;
import org.geneanet.customcamera.BitmapUtils;
import org.geneanet.customcamera.TmpFileUtils;
import org.xmlpull.v1.XmlPullParserException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
@@ -65,7 +66,7 @@ public class CameraActivity extends Activity {
// Enable miniature mode.
private boolean modeMiniature = false;
// The image in Bitmap format of the preview photo.
private Bitmap photoTaken = null;
private Boolean photoTaken = false;
// Flag to active or disable opacity function.
private Boolean opacity = true;
// Flag to save state of flash -> 0 : off, 1 : on, 2 : auto.
@@ -82,6 +83,10 @@ public class CameraActivity extends Activity {
public static final int CAMERA_BACK = 0;
public static final int CAMERA_FRONT = 1;
public static final String NAME_FILE_BACKGROUND = "background";
public static final String NAME_FILE_BACKGROUND_OTHER = "background-other";
public static final String NAME_FILE_PICTURE_TAKEN = "picture-taken";
/**
* To get camera resource or stop this activity.
@@ -292,7 +297,7 @@ public class CameraActivity extends Activity {
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("modeMiniature", modeMiniature);
outState.putParcelable("photoTaken", photoTaken);
outState.putBoolean("photoTaken", photoTaken);
outState.putInt("stateFlash", stateFlash);
super.onSaveInstanceState(outState);
}
@@ -301,7 +306,7 @@ public class CameraActivity extends Activity {
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
modeMiniature = savedInstanceState.getBoolean("modeMiniature");
photoTaken = savedInstanceState.getParcelable("photoTaken");
photoTaken = savedInstanceState.getBoolean("photoTaken");
stateFlash = savedInstanceState.getInt("stateFlash");
if (modeMiniature) {
@@ -328,7 +333,7 @@ public class CameraActivity extends Activity {
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
if (photoTaken == null) {
if (!photoTaken) {
Camera.Parameters paramsCamera = customCamera.getParameters();
int action = event.getAction();
@@ -460,46 +465,25 @@ public class CameraActivity extends Activity {
/** To set background in the view. */
protected void setBackground() {
// Get the base64 picture for the background only if it's exist.
byte[] imgBackgroundBase64;
byte[] imgBackgroundBase64 = null;
File fileBackgroundOther = getFileStreamPath(NAME_FILE_BACKGROUND_OTHER);
if (
TransferBigData.getImgBackgroundBase64OtherOrientation() == null ||
!fileBackgroundOther.exists() ||
this.getIntent().getIntExtra("startOrientation", 1)
== this.getResources().getConfiguration().orientation
) {
imgBackgroundBase64 = TransferBigData.getImgBackgroundBase64();
imgBackgroundBase64 = TmpFileUtils.getTmpFileContent(this, NAME_FILE_BACKGROUND);
} else {
imgBackgroundBase64 = TransferBigData.getImgBackgroundBase64OtherOrientation();
imgBackgroundBase64 = TmpFileUtils.getTmpFileContent(this, NAME_FILE_BACKGROUND_OTHER);
}
if (imgBackgroundBase64 != null) {
// Get sizes screen.
Display defaultDisplay = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
defaultDisplay.getMetrics(displayMetrics);
int displayWidthPx = (int) displayMetrics.widthPixels;
int displayHeightPx = (int) displayMetrics.heightPixels;
// Get picture.
Options options = BitmapUtils.determineOriginalSizePicture(imgBackgroundBase64);
int widthResize = 0;
int heightResize = 0;
int widthBackground = options.outWidth;
int heightBackground= options.outHeight;
float ratioX = (float) displayWidthPx / (float) widthBackground;
float ratioY = (float) displayHeightPx / (float) heightBackground;
if (ratioX < ratioY && ratioX < 1) {
widthResize = (int) displayWidthPx;
heightResize = (int) (ratioX * heightBackground);
} else if (ratioX >= ratioY && ratioY < 1) {
widthResize = (int) (ratioY * widthBackground);
heightResize = (int) displayHeightPx;
}
BitmapUtils.determineInSampleSize(options, displayWidthPx, displayHeightPx);
Bitmap imgBackgroundBitmap = BitmapUtils.decodeOptimalPictureFromByteArray(imgBackgroundBase64, options);
Bitmap imgBackgroundBitmap = BitmapUtils.generateOptimizeBitmap(this, imgBackgroundBase64);
imgBackgroundBase64 = null;
// set image at the view.
ImageView background = (ImageView) findViewById(R.id.background);
background.setImageBitmap(imgBackgroundBitmap);
imgBackgroundBitmap = null;
// Opacity at the beginning
if (opacity) {
background.setAlpha((float)0.5);
@@ -507,16 +491,15 @@ public class CameraActivity extends Activity {
background.setAlpha((float)1);
}
RelativeLayout.LayoutParams paramsMiniature = new RelativeLayout.LayoutParams(widthResize, heightResize);
RelativeLayout.LayoutParams paramsMiniature = (RelativeLayout.LayoutParams) background.getLayoutParams();
paramsMiniature.addRule(RelativeLayout.CENTER_IN_PARENT,
RelativeLayout.TRUE);
background.setLayoutParams(paramsMiniature);
}
}
/**
* Resize and mask the miniature button.
* Resize the picture and change the icon of button.
* @param view
*/
public void buttonMiniature(View view) {
@@ -586,7 +569,7 @@ public class CameraActivity extends Activity {
// Position at the left
paramsMiniature.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
if (photoTaken != null) {
if (photoTaken) {
Resources res = getResources();
int defaultPadding = (int)res.getDimension(R.dimen.default_padding);
@@ -621,7 +604,7 @@ public class CameraActivity extends Activity {
switchOpacity.setVisibility(View.GONE);
}
if (photoTaken != null) {
if (photoTaken) {
// Show/hide elements when a photo is taken
keepPhoto.setVisibility(View.VISIBLE);
photo.setVisibility(View.GONE);
@@ -674,7 +657,7 @@ public class CameraActivity extends Activity {
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Configuration config = getResources().getConfiguration();
int rotation = windowManager.getDefaultDisplay().getRotation();
if (
(
config.orientation == Configuration.ORIENTATION_LANDSCAPE
@@ -708,22 +691,12 @@ public class CameraActivity extends Activity {
/**
* Method to take picture.
*/
public void takePhoto() {
// Handles the moment where picture is taken
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
}
};
// Handles data for raw picture
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
}
};
public void takePhoto() {
setRotationPictureTaken();
final CameraActivity cameraActivityCurrent = this;
// Handles data for jpeg picture
PictureCallback jpegCallback = new PictureCallback() {
/**
* Event when picture is taken.
* @param byte[] data Picture with byte format.
@@ -731,57 +704,55 @@ public class CameraActivity extends Activity {
*/
public void onPictureTaken(byte[] data, Camera camera) {
// Preview from camera
photoTaken = BitmapFactory.decodeByteArray(data, 0, data.length);
// Matrix to perform rotation
Matrix mat = new Matrix();
int defaultOrientation = getDeviceDefaultOrientation();
int orientationCamera = getOrientationOfCamera();
int redirect = CameraActivity.DEGREE_0;
switch (getCustomRotation()) {
case 0:
redirect = CameraActivity.DEGREE_90;
if (ManagerCamera.currentCameraIsFacingFront() || orientationCamera == 1) {
redirect = CameraActivity.DEGREE_270;
photoTaken = true;
TmpFileUtils.createTmpFile(cameraActivityCurrent, NAME_FILE_PICTURE_TAKEN, data);
// Determine if the picture need to be rotated.
File filePictureTaken = getFileStreamPath(NAME_FILE_PICTURE_TAKEN);
int rotate = TmpFileUtils.determineRotateBasedOnExifFromFilePath(filePictureTaken.getAbsolutePath());
if (rotate != 0) {// the picture need to be rotated.
// Temporarily storage to use for decoding
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inTempStorage = new byte[16 * 1024];
FileInputStream fis;
Bitmap photoTakenBitmap;
try {
fis = openFileInput(NAME_FILE_PICTURE_TAKEN);
photoTakenBitmap = BitmapFactory.decodeStream(fis, null, opt);
fis.close();
Matrix mat = new Matrix();
mat.postRotate(rotate);
try {
photoTakenBitmap = Bitmap.createBitmap(photoTakenBitmap, 0, 0, photoTakenBitmap.getWidth(), photoTakenBitmap.getHeight(), mat, true);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photoTakenBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] byteArray = stream.toByteArray();
stream.close();
TmpFileUtils.createTmpFile(cameraActivityCurrent, NAME_FILE_PICTURE_TAKEN, byteArray);
byteArray = null;
} catch (OutOfMemoryError oom) {
Log.e("customCamera", "Can't rotate the picture (out of memory).");
}
break;
case 1:
redirect = CameraActivity.DEGREE_0;
break;
case 2:
// Only on device with landscape mode by default.
if (defaultOrientation == Configuration.ORIENTATION_LANDSCAPE) {
redirect = CameraActivity.DEGREE_270;
}
if (ManagerCamera.currentCameraIsFacingFront() || orientationCamera == 1) {
redirect = CameraActivity.DEGREE_90;
}
break;
case 3:
redirect = CameraActivity.DEGREE_180;
break;
default:
break;
}
mat.postRotate(redirect);
// We execute a mirror to the matrix in case of front camera.
if (ManagerCamera.currentCameraIsFacingFront() || orientationCamera == 1 ) {
if (getCustomRotation() == 0 || getCustomRotation() == 2) {
mat.preScale(1.0f, -1.0f);
} else if (getCustomRotation() == 1 || getCustomRotation() == 3) {
mat.preScale(-1.0f, 1.0f);
} catch (FileNotFoundException e) {
Log.e("customCamera", "Can't load the picture to rotate it.");
} catch (IOException e) {
Log.e("customCamera", "Can't close the file picture. Error message: "+e.getMessage());
} catch (OutOfMemoryError oom) {
Log.e("customCamera", "Can't laod the picture.");
}
photoTakenBitmap = null;
}
// Creation of the bitmap
photoTaken = Bitmap.createBitmap(photoTaken, 0, 0,
photoTaken.getWidth(), photoTaken.getHeight(), mat, true);
displayPicture();
}
};
// Start capture picture.
customCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
customCamera.takePicture(null, null, jpegCallback);
}
/**
@@ -790,13 +761,26 @@ public class CameraActivity extends Activity {
*/
public void acceptPhoto(View view) {
final CameraActivity cameraActivityCurrent = this;
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photoTaken.compress(
CompressFormat.JPEG, this.getIntent().getIntExtra("quality", 100), stream);
BitmapFactory.Options opt = new BitmapFactory.Options();
// Temporarily storage to use for decoding
opt.inTempStorage = new byte[16 * 1024];
byte[] data = TmpFileUtils.getTmpFileContent(this, NAME_FILE_PICTURE_TAKEN);
TransferBigData.setImgTaken(stream.toByteArray());
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Bitmap photoTakenBitmap;
try {
photoTakenBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opt);
photoTakenBitmap.compress(
CompressFormat.JPEG, this.getIntent().getIntExtra("quality", 100), stream);
data = stream.toByteArray();
// rewrite the file with the compression.
TmpFileUtils.createTmpFile(cameraActivityCurrent, NAME_FILE_PICTURE_TAKEN, data);
} catch (OutOfMemoryError oom) {
Log.e("customCamera", "Can't compress the picture taken (out of memory).");
}
photoTakenBitmap = null;
stream.close();
if (this.getIntent().getBooleanExtra("saveInGallery", false)) {
// Get path picture to storage.
@@ -807,14 +791,16 @@ public class CameraActivity extends Activity {
// Write data in file.
FileOutputStream outStream = new FileOutputStream(pathPicture);
outStream.write(TransferBigData.getImgTaken());
outStream.write(data);
data = null;
outStream.close();
}
// Return to success & finish current activity.
cameraActivityCurrent.setResult(1,new Intent());
cameraActivityCurrent.finish();
} catch (IOException e) {
Log.e("customCamera", "Error to write in file: "+e.getMessage());
}
}
@@ -845,7 +831,7 @@ public class CameraActivity extends Activity {
customCamera.setParameters(params);
}
photoTaken = null;
photoTaken = false;
displayPicture();
}
@@ -854,13 +840,28 @@ public class CameraActivity extends Activity {
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
ImageView photoResized = (ImageView) findViewById(R.id.photoResized);
if (photoTaken != null) {
if (photoTaken) {
// Stop link between view and camera to start the preview
// picture.
customCamera.stopPreview();
Bitmap newBitmap = resizePictureTaken();
byte[] data = TmpFileUtils.getTmpFileContent(this, NAME_FILE_PICTURE_TAKEN);
Bitmap newBitmap = BitmapUtils.generateOptimizeBitmap(this, data);
// rotate the picture of need.
File filePictureTaken = getFileStreamPath(NAME_FILE_PICTURE_TAKEN);
int rotate = TmpFileUtils.determineRotateBasedOnExifFromFilePath(filePictureTaken.getAbsolutePath());
if (rotate != 0) {
Matrix mat = new Matrix();
mat.postRotate(rotate);
try {
newBitmap = Bitmap.createBitmap(newBitmap, 0, 0, newBitmap.getWidth(), newBitmap.getHeight(), mat, true);
} catch (OutOfMemoryError oom) {
Log.e("customCamera", "Can't rotate the picture taken (out of memory).");
}
}
photoResized.setImageBitmap(newBitmap);
newBitmap = null;
photoResized.setVisibility(View.VISIBLE);
preview.setVisibility(View.GONE);
} else {
@@ -871,40 +872,6 @@ public class CameraActivity extends Activity {
manageDisplayButtons();
}
/**
* Resize the bitmap saved when you rotate the device.
*
* @return the new bitmap.
*/
protected Bitmap resizePictureTaken() {
// Initialize the new bitmap resized
Bitmap newBitmap = null;
// Get sizes screen.
Display defaultDisplay = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
defaultDisplay.getMetrics(displayMetrics);
int displayWidthPx = (int) displayMetrics.widthPixels;
int displayHeightPx = (int) displayMetrics.heightPixels;
// Get sizes picture.
int widthBackground = (int) (photoTaken.getWidth() * displayMetrics.density);
int heightBackground = (int) (photoTaken.getHeight() * displayMetrics.density);
// Change size ImageView.
float ratioX = (float) displayWidthPx / (float) widthBackground;
float ratioY = (float) displayHeightPx / (float) heightBackground;
if (ratioX < ratioY) {
newBitmap = Bitmap.createScaledBitmap(photoTaken, (int) displayWidthPx,
(int) (ratioX * heightBackground), false);
} else if (ratioX >= ratioY) {
newBitmap = Bitmap.createScaledBitmap(photoTaken,
(int) (ratioY * widthBackground), (int) displayHeightPx, false);
}
return newBitmap;
}
/**
* Allow to lock the screen or not.
@@ -944,7 +911,7 @@ public class CameraActivity extends Activity {
*/
protected int getCustomRotation() {
int code = this.getWindowManager().getDefaultDisplay().getRotation();
if (getDeviceDefaultOrientation() == 2) {
if (getDeviceDefaultOrientation() == Configuration.ORIENTATION_LANDSCAPE) {
code ++;
}
@@ -1094,4 +1061,42 @@ public class CameraActivity extends Activity {
camParameters.setPreviewSize(optimalSize.width, optimalSize.height);
customCamera.setParameters(camParameters);
}
/**
* To set the orientation of the picture taken.
*/
private void setRotationPictureTaken() {
int defaultOrientation = getDeviceDefaultOrientation();
int orientationCamera = getOrientationOfCamera();
int redirect = CameraActivity.DEGREE_0;
switch (getCustomRotation()) {
case 0:
redirect = CameraActivity.DEGREE_90;
if (ManagerCamera.currentCameraIsFacingFront() || orientationCamera == 1) {
redirect = CameraActivity.DEGREE_270;
}
break;
case 1:
redirect = CameraActivity.DEGREE_0;
break;
case 2:
// Only on device with landscape mode by default.
if (defaultOrientation == Configuration.ORIENTATION_LANDSCAPE) {
redirect = CameraActivity.DEGREE_270;
}
if (ManagerCamera.currentCameraIsFacingFront() || orientationCamera == 1) {
redirect = CameraActivity.DEGREE_90;
}
break;
case 3:
redirect = CameraActivity.DEGREE_180;
break;
default:
break;
}
Parameters params = customCamera.getParameters();
params.setRotation(redirect);
customCamera.setParameters(params);
}
}
@@ -0,0 +1,101 @@
package org.geneanet.customcamera;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.content.Context;
import android.media.ExifInterface;
import android.util.Log;
public class TmpFileUtils {
/**
* Create a tmp file in app directory.
*
* @param activity To storage in tmp directory of the activity.
* @param fileName File name.
* @param img Image in bytes.
*/
public static void createTmpFile(Activity activity, String fileName, byte[] img) {
FileOutputStream fos = null;
try {
fos = activity.openFileOutput(fileName, Context.MODE_PRIVATE);
try {
fos.write(img);
fos.close();
} catch (IOException e1) {
Log.e("customCamera", "Can't write or close the file: "+fileName);
}
} catch (FileNotFoundException e1) {
Log.e("customCamera", "Can't open the file: "+fileName);
}
}
/**
* Get the file content from this name.
*
* @param activity To getin tmp directory of the activity.
* @param fileName
*
* @return byte[]
*/
public static byte[] getTmpFileContent(Activity activity, String fileName) {
FileInputStream fis = null;
ByteArrayOutputStream ous = null;
byte[] returnValue = null;
try {
byte[] buffer = new byte[4096];
ous = new ByteArrayOutputStream();
fis = activity.openFileInput(fileName);
int read = 0;
while ( (read = fis.read(buffer)) != -1 ) {
ous.write(buffer, 0, read);
}
fis.close();
returnValue = ous.toByteArray();
ous.close();
} catch (FileNotFoundException e) {
Log.e("customCamera", "Can't open the file: "+fileName);
} catch (IOException e1) {
Log.e("customCamera", "Can't read or close the file: "+fileName);
}
return returnValue;
}
/**
* determine the rotate for a picture based on exif data.
*
* @param filePath
*
* @return int
*/
public static int determineRotateBasedOnExifFromFilePath(String filePath) {
ExifInterface exif;
int rotate = 0;
try {
exif = new ExifInterface(filePath);
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (IOException e) {
Log.e("customCamera", "Can't determine EXIF orientation of :"+filePath+". Error message: "+e.getMessage());
}
return rotate;
}
}
@@ -1,64 +0,0 @@
package org.geneanet.customcamera;
/**
* Use to transfer big data between activities.
*/
public class TransferBigData {
protected static byte[] imgBackgroundBase64 = null;
protected static byte[] imgBackgroundBase64OtherOrientation = null;
protected static byte[] imgTaken = null;
/**
* Get bytes to represent background picture.
*
* @return byte[]
*/
public static byte[] getImgBackgroundBase64() {
return TransferBigData.imgBackgroundBase64;
}
/**
* Set bytes to represent background picture.
*
* @param byte[] imgBackgroundBase64
*/
public static void setImgBackgroundBase64(byte[] imgBackgroundBase64) {
TransferBigData.imgBackgroundBase64 = imgBackgroundBase64;
}
/**
* Get bytes to represent background picture for OtherOrientation.
*
* @return byte[]
*/
public static byte[] getImgBackgroundBase64OtherOrientation() {
return TransferBigData.imgBackgroundBase64OtherOrientation;
}
/**
* Set bytes to represent background picture for OtherOrientation.
*
* @param byte[] imgBackgroundBase64OtherOrientation
*/
public static void setImgBackgroundBase64OtherOrientation(byte[] imgBackgroundBase64OtherOrientation) {
TransferBigData.imgBackgroundBase64OtherOrientation = imgBackgroundBase64OtherOrientation;
}
/**
* Get bytes to represent picture taken.
*
* @return byte[]
*/
public static byte[] getImgTaken() {
return TransferBigData.imgTaken;
}
/**
* Set bytes to represent picture taken.
*
* @param byte[] imgTaken
*/
public static void setImgTaken(byte[] imgTaken) {
TransferBigData.imgTaken = imgTaken;
}
}