fix image preview rotation in ComposeActivity (#831)
This commit is contained in:
parent
0b3bee0d15
commit
aac63441d7
3 changed files with 111 additions and 91 deletions
|
@ -18,6 +18,7 @@ package com.keylesspalace.tusky;
|
|||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ProgressDialog;
|
||||
import android.arch.lifecycle.Lifecycle;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
|
@ -135,12 +136,20 @@ import java.util.Locale;
|
|||
import javax.inject.Inject;
|
||||
|
||||
import at.connyduck.sparkbutton.helpers.Utils;
|
||||
import io.reactivex.Single;
|
||||
import io.reactivex.SingleObserver;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.MultipartBody;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
import static com.uber.autodispose.AutoDispose.autoDisposable;
|
||||
import static com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider.from;
|
||||
|
||||
public final class ComposeActivity
|
||||
extends BaseActivity
|
||||
implements ComposeOptionsListener,
|
||||
|
@ -1121,11 +1130,24 @@ public final class ComposeActivity
|
|||
DisplayMetrics displayMetrics = new DisplayMetrics();
|
||||
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
|
||||
|
||||
Picasso.with(this)
|
||||
.load(item.uri)
|
||||
.resize(displayMetrics.widthPixels, displayMetrics.heightPixels)
|
||||
.onlyScaleDown()
|
||||
.into(imageView);
|
||||
Single.fromCallable(() ->
|
||||
MediaUtils.getSampledBitmap(getContentResolver(), item.uri, displayMetrics.widthPixels, displayMetrics.heightPixels))
|
||||
.subscribeOn(Schedulers.computation())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.as(autoDisposable(from(this, Lifecycle.Event.ON_DESTROY)))
|
||||
.subscribe(new SingleObserver<Bitmap>() {
|
||||
@Override
|
||||
public void onSubscribe(Disposable d) {}
|
||||
|
||||
@Override
|
||||
public void onSuccess(Bitmap bitmap) {
|
||||
imageView.setImageBitmap(bitmap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) { }
|
||||
});
|
||||
|
||||
|
||||
int margin = Utils.dpToPx(this, 4);
|
||||
dialogLayout.addView(imageView);
|
||||
|
|
|
@ -18,16 +18,11 @@ package com.keylesspalace.tusky.util;
|
|||
import android.content.ContentResolver;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.media.ExifInterface;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -37,7 +32,6 @@ import java.util.List;
|
|||
* aspect ratio and orientation.
|
||||
*/
|
||||
public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> {
|
||||
private static final String TAG = "DownsizeImageTask";
|
||||
private int sizeLimit;
|
||||
private ContentResolver contentResolver;
|
||||
private Listener listener;
|
||||
|
@ -54,83 +48,6 @@ public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> {
|
|||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Bitmap reorientBitmap(Bitmap bitmap, int orientation) {
|
||||
Matrix matrix = new Matrix();
|
||||
switch (orientation) {
|
||||
default:
|
||||
case ExifInterface.ORIENTATION_NORMAL: {
|
||||
return bitmap;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: {
|
||||
matrix.setScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_ROTATE_180: {
|
||||
matrix.setRotate(180);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_FLIP_VERTICAL: {
|
||||
matrix.setRotate(180);
|
||||
matrix.postScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_TRANSPOSE: {
|
||||
matrix.setRotate(90);
|
||||
matrix.postScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_ROTATE_90: {
|
||||
matrix.setRotate(90);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_TRANSVERSE: {
|
||||
matrix.setRotate(-90);
|
||||
matrix.postScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_ROTATE_270: {
|
||||
matrix.setRotate(-90);
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
|
||||
bitmap.getHeight(), matrix, true);
|
||||
if (!bitmap.sameAs(result)) {
|
||||
bitmap.recycle();
|
||||
}
|
||||
return result;
|
||||
} catch (OutOfMemoryError e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static int getOrientation(Uri uri, ContentResolver contentResolver) {
|
||||
InputStream inputStream;
|
||||
try {
|
||||
inputStream = contentResolver.openInputStream(uri);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.d(TAG, Log.getStackTraceString(e));
|
||||
return ExifInterface.ORIENTATION_UNDEFINED;
|
||||
}
|
||||
if (inputStream == null) {
|
||||
return ExifInterface.ORIENTATION_UNDEFINED;
|
||||
}
|
||||
ExifInterface exifInterface;
|
||||
try {
|
||||
exifInterface = new ExifInterface(inputStream);
|
||||
} catch (IOException e) {
|
||||
Log.d(TAG, Log.getStackTraceString(e));
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
return ExifInterface.ORIENTATION_UNDEFINED;
|
||||
}
|
||||
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
return orientation;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Uri... uris) {
|
||||
resultList = new ArrayList<>();
|
||||
|
@ -147,7 +64,7 @@ public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> {
|
|||
BitmapFactory.decodeStream(inputStream, null, options);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
// Get EXIF data, for orientation info.
|
||||
int orientation = getOrientation(uri, contentResolver);
|
||||
int orientation = MediaUtils.getImageOrientation(uri, contentResolver);
|
||||
// Then use that information to determine how much to compress.
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
/* Unfortunately, there isn't a determined worst case compression ratio for image
|
||||
|
@ -176,7 +93,7 @@ public class DownsizeImageTask extends AsyncTask<Uri, Void, Boolean> {
|
|||
if (scaledBitmap == null) {
|
||||
return false;
|
||||
}
|
||||
Bitmap reorientedBitmap = reorientBitmap(scaledBitmap, orientation);
|
||||
Bitmap reorientedBitmap = MediaUtils.reorientBitmap(scaledBitmap, orientation);
|
||||
if (reorientedBitmap == null) {
|
||||
scaledBitmap.recycle();
|
||||
return false;
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.content.Context;
|
|||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Matrix;
|
||||
import android.media.MediaMetadataRetriever;
|
||||
import android.media.ThumbnailUtils;
|
||||
import android.net.Uri;
|
||||
|
@ -27,6 +28,7 @@ import android.provider.OpenableColumns;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.Px;
|
||||
import android.support.media.ExifInterface;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -111,7 +113,9 @@ public class MediaUtils {
|
|||
options.inJustDecodeBounds = false;
|
||||
try {
|
||||
stream = contentResolver.openInputStream(uri);
|
||||
return BitmapFactory.decodeStream(stream, null, options);
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
|
||||
int orientation = getImageOrientation(uri, contentResolver);
|
||||
return reorientBitmap(bitmap, orientation);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
|
@ -176,4 +180,81 @@ public class MediaUtils {
|
|||
|
||||
return inSampleSize;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Bitmap reorientBitmap(Bitmap bitmap, int orientation) {
|
||||
Matrix matrix = new Matrix();
|
||||
switch (orientation) {
|
||||
default:
|
||||
case ExifInterface.ORIENTATION_NORMAL: {
|
||||
return bitmap;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL: {
|
||||
matrix.setScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_ROTATE_180: {
|
||||
matrix.setRotate(180);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_FLIP_VERTICAL: {
|
||||
matrix.setRotate(180);
|
||||
matrix.postScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_TRANSPOSE: {
|
||||
matrix.setRotate(90);
|
||||
matrix.postScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_ROTATE_90: {
|
||||
matrix.setRotate(90);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_TRANSVERSE: {
|
||||
matrix.setRotate(-90);
|
||||
matrix.postScale(-1, 1);
|
||||
break;
|
||||
}
|
||||
case ExifInterface.ORIENTATION_ROTATE_270: {
|
||||
matrix.setRotate(-90);
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
|
||||
bitmap.getHeight(), matrix, true);
|
||||
if (!bitmap.sameAs(result)) {
|
||||
bitmap.recycle();
|
||||
}
|
||||
return result;
|
||||
} catch (OutOfMemoryError e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getImageOrientation(Uri uri, ContentResolver contentResolver) {
|
||||
InputStream inputStream;
|
||||
try {
|
||||
inputStream = contentResolver.openInputStream(uri);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, e);
|
||||
return ExifInterface.ORIENTATION_UNDEFINED;
|
||||
}
|
||||
if (inputStream == null) {
|
||||
return ExifInterface.ORIENTATION_UNDEFINED;
|
||||
}
|
||||
ExifInterface exifInterface;
|
||||
try {
|
||||
exifInterface = new ExifInterface(inputStream);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
return ExifInterface.ORIENTATION_UNDEFINED;
|
||||
}
|
||||
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION,
|
||||
ExifInterface.ORIENTATION_NORMAL);
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
return orientation;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue