Search in sources :

Example 1 with ExifInterface

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;
    }
}
Also used : ExifInterface(androidx.exifinterface.media.ExifInterface)

Example 2 with ExifInterface

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;
}
Also used : WritableMap(com.facebook.react.bridge.WritableMap) ExifInterface(androidx.exifinterface.media.ExifInterface) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ByteArrayInputStream(java.io.ByteArrayInputStream) FileOutputStream(java.io.FileOutputStream) ReadableMap(com.facebook.react.bridge.ReadableMap) BitmapFactory(android.graphics.BitmapFactory) Resources(android.content.res.Resources) File(java.io.File)

Example 3 with ExifInterface

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;
    }
}
Also used : ExifInterface(androidx.exifinterface.media.ExifInterface) Paint(android.graphics.Paint)

Example 4 with ExifInterface

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);
}
Also used : InputStream(java.io.InputStream) ExifInterface(androidx.exifinterface.media.ExifInterface) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException)

Example 5 with ExifInterface

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;
}
Also used : ExifInterface(androidx.exifinterface.media.ExifInterface) Cursor(android.database.Cursor) Paint(android.graphics.Paint) Point(android.graphics.Point) AnyThread(androidx.annotation.AnyThread)

Aggregations

ExifInterface (androidx.exifinterface.media.ExifInterface)15 IOException (java.io.IOException)10 InputStream (java.io.InputStream)5 Paint (android.graphics.Paint)4 Bitmap (android.graphics.Bitmap)3 FileNotFoundException (java.io.FileNotFoundException)3 SuppressLint (android.annotation.SuppressLint)2 Cursor (android.database.Cursor)2 Point (android.graphics.Point)2 Pair (android.util.Pair)2 AnyThread (androidx.annotation.AnyThread)2 WorkerThread (androidx.annotation.WorkerThread)2 GifDrawable (com.bumptech.glide.load.resource.gif.GifDrawable)2 FileOutputStream (java.io.FileOutputStream)2 ExecutionException (java.util.concurrent.ExecutionException)2 DecryptableUri (org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri)2 Resources (android.content.res.Resources)1 BitmapFactory (android.graphics.BitmapFactory)1 Matrix (android.graphics.Matrix)1 ImageProcessingException (com.drew.imaging.ImageProcessingException)1