diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/ZoomingImageView.java b/app/src/main/java/org/thoughtcrime/securesms/components/ZoomingImageView.java index 18f6da931..2938921bf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/ZoomingImageView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/ZoomingImageView.java @@ -8,6 +8,7 @@ import android.view.View; import android.widget.FrameLayout; import androidx.annotation.NonNull; +import androidx.exifinterface.media.ExifInterface; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.request.target.Target; @@ -66,9 +67,6 @@ public class ZoomingImageView extends FrameLayout { this.photoView = findViewById(R.id.image_view); this.subsamplingImageView = findViewById(R.id.subsampling_image_view); - this.subsamplingImageView.setOrientation(SubsamplingScaleImageView.ORIENTATION_USE_EXIF); - this.subsamplingImageView.setOrientation(SubsamplingScaleImageView.ORIENTATION_USE_EXIF); - this.photoView.setZoomTransitionDuration(ZOOM_TRANSITION_DURATION); this.photoView.setScaleLevels(ZOOM_LEVEL_MIN, SMALL_IMAGES_ZOOM_LEVEL_MID, SMALL_IMAGES_ZOOM_LEVEL_MAX); @@ -129,6 +127,26 @@ public class ZoomingImageView extends FrameLayout { subsamplingImageView.setVisibility(View.VISIBLE); photoView.setVisibility(View.GONE); + // We manually set the orientation ourselves because using + // SubsamplingScaleImageView.ORIENTATION_USE_EXIF is unreliable: + // https://github.com/signalapp/Signal-Android/issues/11732#issuecomment-963203545 + try { + final InputStream inputStream = PartAuthority.getAttachmentStream(getContext(), uri); + final int orientation = BitmapUtil.getExifOrientation(new ExifInterface(inputStream)); + inputStream.close(); + if (orientation == ExifInterface.ORIENTATION_ROTATE_90) { + subsamplingImageView.setOrientation(SubsamplingScaleImageView.ORIENTATION_90); + } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) { + subsamplingImageView.setOrientation(SubsamplingScaleImageView.ORIENTATION_180); + } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) { + subsamplingImageView.setOrientation(SubsamplingScaleImageView.ORIENTATION_270); + } else { + subsamplingImageView.setOrientation(SubsamplingScaleImageView.ORIENTATION_0); + } + } catch (IOException e) { + Log.w(TAG, e); + } + subsamplingImageView.setImage(ImageSource.uri(uri)); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java index 33cf9b0c2..72cebbec4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/BitmapUtil.java @@ -244,16 +244,19 @@ public class BitmapUtil { return options; } + public static int getExifOrientation(ExifInterface exif) { + return exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED); + } + @Nullable - public static Pair getExifDimensions(InputStream inputStream) throws IOException { - ExifInterface exif = new ExifInterface(inputStream); - int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0); - int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0); + public static Pair getExifDimensions(ExifInterface exif) { + int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0); + int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0); if (width == 0 || height == 0) { return null; } - int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0); + int orientation = getExifOrientation(exif); if (orientation == ExifInterface.ORIENTATION_ROTATE_90 || orientation == ExifInterface.ORIENTATION_ROTATE_270 || orientation == ExifInterface.ORIENTATION_TRANSVERSE || diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java index 9684e3ce5..e72304694 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java +++ b/app/src/main/java/org/thoughtcrime/securesms/util/MediaUtil.java @@ -17,6 +17,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.annotation.WorkerThread; +import androidx.exifinterface.media.ExifInterface; import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.resource.gif.GifDrawable; @@ -189,7 +190,7 @@ public class MediaUtil { try { if (MediaUtil.isJpegType(contentType)) { attachmentStream = PartAuthority.getAttachmentStream(context, uri); - dimens = BitmapUtil.getExifDimensions(attachmentStream); + dimens = BitmapUtil.getExifDimensions(new ExifInterface(attachmentStream)); attachmentStream.close(); attachmentStream = null; }