use of androidx.exifinterface.media.ExifInterface in project uCrop by Yalantis.
the class BitmapCropTask method crop.
private boolean crop(float resizeScale) throws IOException {
ExifInterface originalExif = new ExifInterface(mImageInputPath);
cropOffsetX = Math.round((mCropRect.left - mCurrentImageRect.left) / mCurrentScale);
cropOffsetY = Math.round((mCropRect.top - mCurrentImageRect.top) / mCurrentScale);
mCroppedImageWidth = Math.round(mCropRect.width() / mCurrentScale);
mCroppedImageHeight = Math.round(mCropRect.height() / mCurrentScale);
boolean shouldCrop = shouldCrop(mCroppedImageWidth, mCroppedImageHeight);
Log.i(TAG, "Should crop: " + shouldCrop);
if (shouldCrop) {
boolean cropped = cropCImg(mImageInputPath, mImageOutputPath, cropOffsetX, cropOffsetY, mCroppedImageWidth, mCroppedImageHeight, mCurrentAngle, resizeScale, mCompressFormat.ordinal(), mCompressQuality, mExifInfo.getExifDegrees(), mExifInfo.getExifTranslation());
if (cropped && mCompressFormat.equals(Bitmap.CompressFormat.JPEG)) {
ImageHeaderParser.copyExif(originalExif, mCroppedImageWidth, mCroppedImageHeight, mImageOutputPath);
}
return cropped;
} else {
FileUtils.copyFile(mImageInputPath, mImageOutputPath);
return false;
}
}
use of androidx.exifinterface.media.ExifInterface in project react-native-camera by lwansbrough.
the class ResolveTakenPictureAsyncTask method doInBackground.
@Override
protected WritableMap doInBackground(Void... voids) {
WritableMap response = Arguments.createMap();
ByteArrayInputStream inputStream = null;
ExifInterface exifInterface = null;
WritableMap exifData = null;
ReadableMap exifExtraData = null;
boolean exifOrientationFixed = false;
response.putInt("deviceOrientation", mDeviceOrientation);
response.putInt("pictureOrientation", mOptions.hasKey("orientation") ? mOptions.getInt("orientation") : mDeviceOrientation);
try {
// this replaces the skipProcessing flag, we will process only if needed, and in
// an orderly manner, so that skipProcessing is the default behaviour if no options are given
// and this behaves more like the iOS version.
// We will load all data lazily only when needed.
// this should not incur in any overhead if not read/used
inputStream = new ByteArrayInputStream(mImageData);
if (mSoftwareRotation != 0) {
loadBitmap();
mBitmap = rotateBitmap(mBitmap, mSoftwareRotation);
}
// Rotate the bitmap to the proper orientation if requested
if (mOptions.hasKey("fixOrientation") && mOptions.getBoolean("fixOrientation")) {
exifInterface = new ExifInterface(inputStream);
// Get orientation of the image from mImageData via inputStream
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
if (orientation != ExifInterface.ORIENTATION_UNDEFINED && getImageRotation(orientation) != 0) {
loadBitmap();
int angle = getImageRotation(orientation);
mBitmap = rotateBitmap(mBitmap, angle);
exifOrientationFixed = true;
}
}
if (mOptions.hasKey("width")) {
loadBitmap();
mBitmap = resizeBitmap(mBitmap, mOptions.getInt("width"));
}
if (mOptions.hasKey("mirrorImage") && mOptions.getBoolean("mirrorImage")) {
loadBitmap();
mBitmap = flipHorizontally(mBitmap);
}
// EXIF code - we will adjust exif info later if we manipulated the bitmap
boolean writeExifToResponse = mOptions.hasKey("exif") && mOptions.getBoolean("exif");
// default to true if not provided so it is consistent with iOS and with what happens if no
// processing is done and the image is saved as is.
boolean writeExifToFile = true;
if (mOptions.hasKey("writeExif")) {
switch(mOptions.getType("writeExif")) {
case Boolean:
writeExifToFile = mOptions.getBoolean("writeExif");
break;
case Map:
exifExtraData = mOptions.getMap("writeExif");
writeExifToFile = true;
break;
}
}
// Read Exif data if needed
if (writeExifToResponse || writeExifToFile) {
// Otherwise we can just use w/e exif data we have right now in our byte array
if (mBitmap != null || exifExtraData != null || writeExifToResponse) {
if (exifInterface == null) {
exifInterface = new ExifInterface(inputStream);
}
exifData = RNCameraViewHelper.getExifData(exifInterface);
if (exifExtraData != null) {
exifData.merge(exifExtraData);
}
}
// if we did anything to the bitmap, adjust exif
if (mBitmap != null) {
exifData.putInt("width", mBitmap.getWidth());
exifData.putInt("height", mBitmap.getHeight());
if (exifOrientationFixed) {
exifData.putInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
}
}
// Write Exif data to the response if requested
if (writeExifToResponse) {
final WritableMap exifDataCopy = Arguments.createMap();
exifDataCopy.merge(exifData);
response.putMap("exif", exifDataCopy);
}
}
// Based on whether or not we loaded the full bitmap into memory, final processing differs
if (mBitmap == null) {
// set response dimensions. If we haven't read our bitmap, get it efficiently
// without loading the actual bitmap into memory
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(mImageData, 0, mImageData.length, options);
if (options != null) {
response.putInt("width", options.outWidth);
response.putInt("height", options.outHeight);
}
// save to file if requested
if (!mOptions.hasKey("doNotSave") || !mOptions.getBoolean("doNotSave")) {
// Prepare file output
File imageFile = new File(getImagePath());
imageFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(imageFile);
// Save byte array (it is already a JPEG)
fOut.write(mImageData);
fOut.flush();
fOut.close();
// Since we didn't modify the image, we only update if we have extra exif info
if (writeExifToFile && exifExtraData != null) {
ExifInterface fileExifInterface = new ExifInterface(imageFile.getAbsolutePath());
RNCameraViewHelper.setExifData(fileExifInterface, exifExtraData);
fileExifInterface.saveAttributes();
} else if (!writeExifToFile) {
// if we were requested to NOT store exif, we actually need to
// clear the exif tags
ExifInterface fileExifInterface = new ExifInterface(imageFile.getAbsolutePath());
RNCameraViewHelper.clearExifData(fileExifInterface);
fileExifInterface.saveAttributes();
}
// else: exif is unmodified, no need to update anything
// Return file system URI
String fileUri = Uri.fromFile(imageFile).toString();
response.putString("uri", fileUri);
}
if (mOptions.hasKey("base64") && mOptions.getBoolean("base64")) {
response.putString("base64", Base64.encodeToString(mImageData, Base64.NO_WRAP));
}
} else {
// get response dimensions right from the bitmap if we have it
response.putInt("width", mBitmap.getWidth());
response.putInt("height", mBitmap.getHeight());
// Cache compressed image in imageStream
ByteArrayOutputStream imageStream = new ByteArrayOutputStream();
if (!mBitmap.compress(Bitmap.CompressFormat.JPEG, getQuality(), imageStream)) {
mPromise.reject(ERROR_TAG, "Could not compress image to JPEG");
return null;
}
// Write compressed image to file in cache directory unless otherwise specified
if (!mOptions.hasKey("doNotSave") || !mOptions.getBoolean("doNotSave")) {
String filePath = writeStreamToFile(imageStream);
// to add it if requested
if (writeExifToFile && exifData != null) {
ExifInterface fileExifInterface = new ExifInterface(filePath);
RNCameraViewHelper.setExifData(fileExifInterface, exifData);
fileExifInterface.saveAttributes();
}
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.NO_WRAP));
}
}
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();
}
}
return null;
}
use of androidx.exifinterface.media.ExifInterface in project Conversations by siacs.
the class FileBackend method getRotation.
private static int getRotation(final InputStream inputStream) throws IOException {
final ExifInterface exif = new ExifInterface(inputStream);
final int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
switch(orientation) {
case ExifInterface.ORIENTATION_ROTATE_180:
return 180;
case ExifInterface.ORIENTATION_ROTATE_90:
return 90;
case ExifInterface.ORIENTATION_ROTATE_270:
return 270;
default:
return 0;
}
}
use of androidx.exifinterface.media.ExifInterface in project Android-Image-Cropper by ArthurHub.
the class BitmapUtils method rotateBitmapByExif.
/**
* Rotate the given image by reading the Exif value of the image (uri).<br>
* If no rotation is required the image will not be rotated.<br>
* New bitmap is created and the old one is recycled.
*/
static RotateBitmapResult rotateBitmapByExif(Bitmap bitmap, Context context, Uri uri) {
ExifInterface ei = null;
try {
InputStream is = context.getContentResolver().openInputStream(uri);
if (is != null) {
ei = new ExifInterface(is);
is.close();
}
} catch (Exception ignored) {
}
return ei != null ? rotateBitmapByExif(bitmap, ei) : new RotateBitmapResult(bitmap, 0);
}
use of androidx.exifinterface.media.ExifInterface in project Slide by ccrama.
the class SubsamplingScaleImageView method getExifOrientation.
/**
* Helper method for load tasks. Examines the EXIF info on the image file to determine the orientation.
* This will only work for external files, not assets, resources or other URIs.
*/
@AnyThread
private int getExifOrientation(Context context, String sourceUri) {
int exifOrientation = ORIENTATION_0;
if (sourceUri.startsWith(ContentResolver.SCHEME_CONTENT)) {
Cursor cursor = null;
try {
String[] columns = { MediaStore.Images.Media.ORIENTATION };
cursor = context.getContentResolver().query(Uri.parse(sourceUri), columns, null, null, null);
if (cursor != null) {
if (cursor.moveToFirst()) {
int orientation = cursor.getInt(0);
if (VALID_ORIENTATIONS.contains(orientation) && orientation != ORIENTATION_USE_EXIF) {
exifOrientation = orientation;
} else {
Log.w(TAG, "Unsupported orientation: " + orientation);
}
}
}
} catch (Exception e) {
Log.w(TAG, "Could not get orientation of image from media store");
} finally {
if (cursor != null) {
cursor.close();
}
}
} else if (sourceUri.startsWith(ImageSource.FILE_SCHEME) && !sourceUri.startsWith(ImageSource.ASSET_SCHEME)) {
try {
ExifInterface exifInterface = new ExifInterface(sourceUri.substring(ImageSource.FILE_SCHEME.length() - 1));
int orientationAttr = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
if (orientationAttr == ExifInterface.ORIENTATION_NORMAL || orientationAttr == ExifInterface.ORIENTATION_UNDEFINED) {
exifOrientation = ORIENTATION_0;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_90) {
exifOrientation = ORIENTATION_90;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_180) {
exifOrientation = ORIENTATION_180;
} else if (orientationAttr == ExifInterface.ORIENTATION_ROTATE_270) {
exifOrientation = ORIENTATION_270;
} else {
Log.w(TAG, "Unsupported EXIF orientation: " + orientationAttr);
}
} catch (Exception e) {
Log.w(TAG, "Could not get EXIF orientation of image");
}
}
return exifOrientation;
}
Aggregations