mirror of
https://github.com/status-im/react-native-camera.git
synced 2025-02-24 09:48:17 +00:00
Add ability to control size by only specifying width + made orientation optionnal. see #768
This commit is contained in:
parent
e064bab7db
commit
983337d9f8
@ -24,18 +24,18 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, WritableMap> {
|
||||
private static final String ERROR_TAG = "E_TAKING_PICTURE_FAILED";
|
||||
private Promise mPromise;
|
||||
private byte[] mImageData;
|
||||
private ReadableMap mOptions;
|
||||
private File mCacheDirectory;
|
||||
private Bitmap mBitmap;
|
||||
private static final String ERROR_TAG = "E_TAKING_PICTURE_FAILED";
|
||||
private Promise mPromise;
|
||||
private byte[] mImageData;
|
||||
private ReadableMap mOptions;
|
||||
private File mCacheDirectory;
|
||||
private Bitmap mBitmap;
|
||||
|
||||
public ResolveTakenPictureAsyncTask(byte[] imageData, Promise promise, ReadableMap options) {
|
||||
mPromise = promise;
|
||||
mOptions = options;
|
||||
mImageData = imageData;
|
||||
}
|
||||
public ResolveTakenPictureAsyncTask(byte[] imageData, Promise promise, ReadableMap options) {
|
||||
mPromise = promise;
|
||||
mOptions = options;
|
||||
mImageData = imageData;
|
||||
}
|
||||
|
||||
public ResolveTakenPictureAsyncTask(byte[] imageData, Promise promise, ReadableMap options, File cacheDirectory) {
|
||||
mPromise = promise;
|
||||
@ -44,95 +44,97 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
|
||||
mCacheDirectory = cacheDirectory;
|
||||
}
|
||||
|
||||
private int getQuality() {
|
||||
return (int) (mOptions.getDouble("quality") * 100);
|
||||
}
|
||||
private int getQuality() {
|
||||
return (int) (mOptions.getDouble("quality") * 100);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WritableMap doInBackground(Void... voids) {
|
||||
WritableMap response = Arguments.createMap();
|
||||
ByteArrayInputStream inputStream = null;
|
||||
@Override
|
||||
protected WritableMap doInBackground(Void... voids) {
|
||||
WritableMap response = Arguments.createMap();
|
||||
ByteArrayInputStream inputStream = null;
|
||||
|
||||
// we need the stream only for photos from a device
|
||||
if (mBitmap == null) {
|
||||
mBitmap = BitmapFactory.decodeByteArray(mImageData, 0, mImageData.length);
|
||||
inputStream = new ByteArrayInputStream(mImageData);
|
||||
}
|
||||
// we need the stream only for photos from a device
|
||||
if (mBitmap == null) {
|
||||
mBitmap = BitmapFactory.decodeByteArray(mImageData, 0, mImageData.length);
|
||||
inputStream = new ByteArrayInputStream(mImageData);
|
||||
}
|
||||
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
if (mOptions.hasKey("width") && mOptions.hasKey("height")) {
|
||||
mBitmap = resizeBitmap(mBitmap, mOptions.getInteger("width"), mOptions.getInteger("height"));
|
||||
}
|
||||
ExifInterface exifInterface = new ExifInterface(inputStream);
|
||||
// Get orientation of the image from mImageData via inputStream
|
||||
int orientation = exifInterface.getAttributeInt(
|
||||
ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_UNDEFINED
|
||||
);
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
ExifInterface exifInterface = new ExifInterface(inputStream);
|
||||
|
||||
// Rotate the bitmap to the proper orientation if needed
|
||||
if (orientation != ExifInterface.ORIENTATION_UNDEFINED) {
|
||||
mBitmap = rotateBitmap(mBitmap, getImageRotation(orientation));
|
||||
}
|
||||
// Get orientation of the image from mImageData via inputStream
|
||||
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_UNDEFINED);
|
||||
|
||||
if (mOptions.hasKey("mirrorImage") && mOptions.getBoolean("mirrorImage")) {
|
||||
mBitmap = flipHorizontally(mBitmap);
|
||||
}
|
||||
if (mOptions.hasKey("width")) {
|
||||
mBitmap = resizeBitmap(mBitmap, mOptions.getInt("width"));
|
||||
}
|
||||
|
||||
// Write Exif data to the response if requested
|
||||
if (mOptions.hasKey("exif") && mOptions.getBoolean("exif")) {
|
||||
WritableMap exifData = RNCameraViewHelper.getExifData(exifInterface);
|
||||
response.putMap("exif", exifData);
|
||||
}
|
||||
}
|
||||
// Rotate the bitmap to the proper orientation if needed and asked
|
||||
if (mOptions.hasKey("fixOrientation") && mOptions.getBoolean("fixOrientation")
|
||||
&& orientation != ExifInterface.ORIENTATION_UNDEFINED) {
|
||||
mBitmap = rotateBitmap(mBitmap, getImageRotation(orientation));
|
||||
}
|
||||
|
||||
// Upon rotating, write the image's dimensions to the response
|
||||
response.putInt("width", mBitmap.getWidth());
|
||||
response.putInt("height", mBitmap.getHeight());
|
||||
if (mOptions.hasKey("mirrorImage") && mOptions.getBoolean("mirrorImage")) {
|
||||
mBitmap = flipHorizontally(mBitmap);
|
||||
}
|
||||
|
||||
// Cache compressed image in imageStream
|
||||
ByteArrayOutputStream imageStream = new ByteArrayOutputStream();
|
||||
mBitmap.compress(Bitmap.CompressFormat.JPEG, getQuality(), imageStream);
|
||||
// Write Exif data to the response if requested
|
||||
if (mOptions.hasKey("exif") && mOptions.getBoolean("exif")) {
|
||||
WritableMap exifData = RNCameraViewHelper.getExifData(exifInterface);
|
||||
response.putMap("exif", exifData);
|
||||
}
|
||||
|
||||
// Write compressed image to file in cache directory
|
||||
String filePath = writeStreamToFile(imageStream);
|
||||
File imageFile = new File(filePath);
|
||||
String fileUri = Uri.fromFile(imageFile).toString();
|
||||
response.putString("uri", fileUri);
|
||||
}
|
||||
|
||||
// Write base64-encoded image to the response if requested
|
||||
if (mOptions.hasKey("base64") && mOptions.getBoolean("base64")) {
|
||||
response.putString("base64", Base64.encodeToString(imageStream.toByteArray(), Base64.DEFAULT));
|
||||
}
|
||||
// Upon rotating, write the image's dimensions to the response
|
||||
response.putInt("width", mBitmap.getWidth());
|
||||
response.putInt("height", mBitmap.getHeight());
|
||||
|
||||
// Cleanup
|
||||
imageStream.close();
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
}
|
||||
// Cache compressed image in imageStream
|
||||
ByteArrayOutputStream imageStream = new ByteArrayOutputStream();
|
||||
mBitmap.compress(Bitmap.CompressFormat.JPEG, getQuality(), imageStream);
|
||||
|
||||
return response;
|
||||
} catch (Resources.NotFoundException e) {
|
||||
mPromise.reject(ERROR_TAG, "Documents directory of the app could not be found.", e);
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
mPromise.reject(ERROR_TAG, "An unknown I/O exception has occurred.", e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// Write compressed image to file in cache directory
|
||||
String filePath = writeStreamToFile(imageStream);
|
||||
File imageFile = new File(filePath);
|
||||
String fileUri = Uri.fromFile(imageFile).toString();
|
||||
response.putString("uri", fileUri);
|
||||
|
||||
// An exception had to occur, promise has already been rejected. Do not try to resolve it again.
|
||||
return null;
|
||||
}
|
||||
// Write base64-encoded image to the response if requested
|
||||
if (mOptions.hasKey("base64") && mOptions.getBoolean("base64")) {
|
||||
response.putString("base64", Base64.encodeToString(imageStream.toByteArray(), Base64.DEFAULT));
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
imageStream.close();
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
inputStream = null;
|
||||
}
|
||||
|
||||
return response;
|
||||
} catch (Resources.NotFoundException e) {
|
||||
mPromise.reject(ERROR_TAG, "Documents directory of the app could not be found.", e);
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
mPromise.reject(ERROR_TAG, "An unknown I/O exception has occurred.", e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (inputStream != null) {
|
||||
inputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// An exception had to occur, promise has already been rejected. Do not try to resolve it again.
|
||||
return null;
|
||||
}
|
||||
|
||||
private Bitmap rotateBitmap(Bitmap source, int angle) {
|
||||
Matrix matrix = new Matrix();
|
||||
@ -140,18 +142,12 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
|
||||
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true);
|
||||
}
|
||||
|
||||
public Bitmap resizeBitmap(Bitmap bm, int newWidth, int newHeight) {
|
||||
private Bitmap resizeBitmap(Bitmap bm, int newWidth) {
|
||||
int width = bm.getWidth();
|
||||
int height = bm.getHeight();
|
||||
float scaleWidth = ((float) newWidth) / width;
|
||||
float scaleHeight = ((float) newHeight) / height;
|
||||
float scaleRatio = (float) newWidth / (float) width;
|
||||
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postScale(scaleWidth, scaleHeight);
|
||||
|
||||
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
|
||||
bm.recycle();
|
||||
return resizedBitmap;
|
||||
return Bitmap.createScaledBitmap(bm, newWidth, (int) (height * scaleRatio), true);
|
||||
}
|
||||
|
||||
private Bitmap flipHorizontally(Bitmap source) {
|
||||
@ -165,56 +161,56 @@ public class ResolveTakenPictureAsyncTask extends AsyncTask<Void, Void, Writable
|
||||
private int getImageRotation(int orientation) {
|
||||
int rotationDegrees = 0;
|
||||
switch (orientation) {
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
rotationDegrees = 90;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
rotationDegrees = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
rotationDegrees = 270;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_90:
|
||||
rotationDegrees = 90;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_180:
|
||||
rotationDegrees = 180;
|
||||
break;
|
||||
case ExifInterface.ORIENTATION_ROTATE_270:
|
||||
rotationDegrees = 270;
|
||||
break;
|
||||
}
|
||||
return rotationDegrees;
|
||||
}
|
||||
|
||||
private String writeStreamToFile(ByteArrayOutputStream inputStream) throws IOException {
|
||||
String outputPath = null;
|
||||
IOException exception = null;
|
||||
FileOutputStream outputStream = null;
|
||||
private String writeStreamToFile(ByteArrayOutputStream inputStream) throws IOException {
|
||||
String outputPath = null;
|
||||
IOException exception = null;
|
||||
FileOutputStream outputStream = null;
|
||||
|
||||
try {
|
||||
outputPath = RNFileUtils.getOutputFilePath(mCacheDirectory, ".jpg");
|
||||
outputStream = new FileOutputStream(outputPath);
|
||||
inputStream.writeTo(outputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
exception = e;
|
||||
} finally {
|
||||
try {
|
||||
if (outputStream != null) {
|
||||
outputStream.close();
|
||||
}
|
||||
outputPath = RNFileUtils.getOutputFilePath(mCacheDirectory, ".jpg");
|
||||
outputStream = new FileOutputStream(outputPath);
|
||||
inputStream.writeTo(outputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
exception = e;
|
||||
} finally {
|
||||
try {
|
||||
if (outputStream != null) {
|
||||
outputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(WritableMap response) {
|
||||
super.onPostExecute(response);
|
||||
|
||||
// If the response is not null everything went well and we can resolve the promise.
|
||||
if (response != null) {
|
||||
mPromise.resolve(response);
|
||||
}
|
||||
}
|
||||
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
return outputPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(WritableMap response) {
|
||||
super.onPostExecute(response);
|
||||
|
||||
// If the response is not null everything went well and we can resolve the promise.
|
||||
if (response != null) {
|
||||
mPromise.resolve(response);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user