mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-03 12:02:18 +00:00
@@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
@@ -13,9 +14,15 @@ import android.util.Log;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.android.gallery3d.data.Exif;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.mms.PartAuthority;
|
||||
|
||||
public class BitmapUtil {
|
||||
private static final String TAG = BitmapUtil.class.getSimpleName();
|
||||
|
||||
@@ -23,20 +30,15 @@ public class BitmapUtil {
|
||||
private static final int MIN_COMPRESSION_QUALITY = 50;
|
||||
private static final int MAX_COMPRESSION_ATTEMPTS = 4;
|
||||
|
||||
public static byte[] createScaledBytes(Context context, Uri uri, int maxWidth,
|
||||
int maxHeight, int maxSize)
|
||||
public static byte[] createScaledBytes(Context context, MasterSecret masterSecret, Uri uri, int maxWidth, int maxHeight, int maxSize)
|
||||
throws IOException, BitmapDecodingException
|
||||
{
|
||||
Bitmap bitmap;
|
||||
try {
|
||||
bitmap = createScaledBitmap(context.getContentResolver().openInputStream(uri),
|
||||
context.getContentResolver().openInputStream(uri),
|
||||
maxWidth, maxHeight, false);
|
||||
bitmap = createScaledBitmap(context, masterSecret, uri, maxWidth, maxHeight, false);
|
||||
} catch(OutOfMemoryError oome) {
|
||||
Log.w(TAG, "OutOfMemoryError when scaling precisely, doing rough scale to save memory instead");
|
||||
bitmap = createScaledBitmap(context.getContentResolver().openInputStream(uri),
|
||||
context.getContentResolver().openInputStream(uri),
|
||||
maxWidth, maxHeight, true);
|
||||
bitmap = createScaledBitmap(context, masterSecret, uri, maxWidth, maxHeight, true);
|
||||
}
|
||||
int quality = MAX_COMPRESSION_QUALITY;
|
||||
int attempts = 0;
|
||||
@@ -56,6 +58,37 @@ public class BitmapUtil {
|
||||
else throw new IOException("Unable to scale image below: " + baos.size());
|
||||
}
|
||||
|
||||
public static Bitmap createScaledBitmap(Context context, MasterSecret masterSecret, Uri uri, int maxWidth, int maxHeight)
|
||||
throws BitmapDecodingException, FileNotFoundException
|
||||
{
|
||||
return createScaledBitmap(context, masterSecret, uri, maxWidth, maxHeight, false);
|
||||
}
|
||||
|
||||
private static Bitmap createScaledBitmap(Context context, MasterSecret masterSecret, Uri uri, int maxWidth, int maxHeight, boolean constrainedMemory)
|
||||
throws FileNotFoundException, BitmapDecodingException
|
||||
{
|
||||
return createScaledBitmap(PartAuthority.getPartStream(context, masterSecret, uri),
|
||||
PartAuthority.getPartStream(context, masterSecret, uri),
|
||||
PartAuthority.getPartStream(context, masterSecret, uri),
|
||||
maxWidth, maxHeight, constrainedMemory);
|
||||
}
|
||||
|
||||
private static Bitmap createScaledBitmap(InputStream measure, InputStream orientationStream, InputStream data,
|
||||
int maxWidth, int maxHeight, boolean constrainedMemory)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
Bitmap bitmap = createScaledBitmap(measure, data, maxWidth, maxHeight, constrainedMemory);
|
||||
return fixOrientation(bitmap, orientationStream);
|
||||
}
|
||||
|
||||
private static Bitmap createScaledBitmap(InputStream measure, InputStream data, int maxWidth, int maxHeight,
|
||||
boolean constrainedMemory)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
final BitmapFactory.Options options = getImageDimensions(measure);
|
||||
return createScaledBitmap(data, maxWidth, maxHeight, options, constrainedMemory);
|
||||
}
|
||||
|
||||
public static Bitmap createScaledBitmap(InputStream measure, InputStream data, float scale)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
@@ -66,21 +99,12 @@ public class BitmapUtil {
|
||||
return createScaledBitmap(data, outWidth, outHeight, options, false);
|
||||
}
|
||||
|
||||
public static Bitmap createScaledBitmap(InputStream measure, InputStream data,
|
||||
int maxWidth, int maxHeight)
|
||||
public static Bitmap createScaledBitmap(InputStream measure, InputStream data, int maxWidth, int maxHeight)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
return createScaledBitmap(measure, data, maxWidth, maxHeight, false);
|
||||
}
|
||||
|
||||
public static Bitmap createScaledBitmap(InputStream measure, InputStream data,
|
||||
int maxWidth, int maxHeight, boolean constrainedMemory)
|
||||
throws BitmapDecodingException
|
||||
{
|
||||
final BitmapFactory.Options options = getImageDimensions(measure);
|
||||
return createScaledBitmap(data, maxWidth, maxHeight, options, constrainedMemory);
|
||||
}
|
||||
|
||||
private static Bitmap createScaledBitmap(InputStream data, int maxWidth, int maxHeight,
|
||||
BitmapFactory.Options options, boolean constrainedMemory)
|
||||
throws BitmapDecodingException
|
||||
@@ -141,6 +165,24 @@ public class BitmapUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap fixOrientation(Bitmap bitmap, InputStream orientationStream) {
|
||||
final int orientation = Exif.getOrientation(orientationStream);
|
||||
|
||||
if (orientation != 0) {
|
||||
return rotateBitmap(bitmap, orientation);
|
||||
} else {
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
private static Bitmap rotateBitmap(Bitmap bitmap, int angle) {
|
||||
Matrix matrix = new Matrix();
|
||||
matrix.postRotate(angle);
|
||||
Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
|
||||
if (rotated != bitmap) bitmap.recycle();
|
||||
return rotated;
|
||||
}
|
||||
|
||||
private static BitmapFactory.Options getImageDimensions(InputStream inputStream) {
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
@@ -160,6 +202,14 @@ public class BitmapUtil {
|
||||
return getScaledCircleCroppedBitmap(bitmap, srcSize);
|
||||
}
|
||||
|
||||
public static Bitmap getScaledCircleCroppedBitmap(Context context, Uri uri, int destSize) throws FileNotFoundException {
|
||||
InputStream dataStream = context.getContentResolver().openInputStream(uri);
|
||||
InputStream orientationStream = context.getContentResolver().openInputStream(uri);
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(dataStream);
|
||||
|
||||
return getScaledCircleCroppedBitmap(fixOrientation(bitmap, orientationStream), destSize);
|
||||
}
|
||||
|
||||
public static Bitmap getScaledCircleCroppedBitmap(Bitmap bitmap, int destSize) {
|
||||
if (bitmap == null) return null;
|
||||
Bitmap output = Bitmap.createBitmap(destSize, destSize, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Reference in New Issue
Block a user