mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-11 01:21:47 +00:00
@@ -813,7 +813,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
||||
|
||||
private void addAttachmentImage(Uri imageUri) {
|
||||
try {
|
||||
attachmentManager.setImage(imageUri);
|
||||
attachmentManager.setImage(masterSecret, imageUri);
|
||||
} catch (IOException | BitmapDecodingException e) {
|
||||
Log.w(TAG, e);
|
||||
attachmentManager.clear();
|
||||
|
||||
@@ -510,14 +510,12 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity {
|
||||
@Override
|
||||
protected Bitmap doInBackground(Void... voids) {
|
||||
if (avatarUri != null) {
|
||||
InputStream inputStream;
|
||||
try {
|
||||
inputStream = getApplicationContext().getContentResolver().openInputStream(avatarUri);
|
||||
avatarBmp = BitmapUtil.getScaledCircleCroppedBitmap(getApplicationContext(), avatarUri, AVATAR_SIZE);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
}
|
||||
avatarBmp = BitmapUtil.getScaledCircleCroppedBitmap(BitmapFactory.decodeStream(inputStream), AVATAR_SIZE);
|
||||
}
|
||||
return avatarBmp;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -61,8 +62,8 @@ public class AttachmentManager {
|
||||
attachmentListener.onAttachmentChanged();
|
||||
}
|
||||
|
||||
public void setImage(Uri image) throws IOException, BitmapDecodingException {
|
||||
setMedia(new ImageSlide(context, image), 345, 261);
|
||||
public void setImage(MasterSecret masterSecret, Uri image) throws IOException, BitmapDecodingException {
|
||||
setMedia(new ImageSlide(context, masterSecret, image), 345, 261);
|
||||
}
|
||||
|
||||
public void setVideo(Uri video) throws IOException, MediaTooLargeException {
|
||||
|
||||
@@ -60,8 +60,8 @@ public class ImageSlide extends Slide {
|
||||
super(context, masterSecret, part);
|
||||
}
|
||||
|
||||
public ImageSlide(Context context, Uri uri) throws IOException, BitmapDecodingException {
|
||||
super(context, constructPartFromUri(context, uri));
|
||||
public ImageSlide(Context context, MasterSecret masterSecret, Uri uri) throws IOException, BitmapDecodingException {
|
||||
super(context, constructPartFromUri(context, masterSecret, uri));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -77,11 +77,9 @@ public class ImageSlide extends Slide {
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream measureStream = getPartDataInputStream();
|
||||
InputStream dataStream = getPartDataInputStream();
|
||||
|
||||
thumbnail = new BitmapDrawable(context.getResources(), BitmapUtil.createScaledBitmap(measureStream, dataStream, maxWidth, maxHeight));
|
||||
thumbnailCache.put(part.getDataUri(), new SoftReference<Drawable>(thumbnail));
|
||||
thumbnail = new BitmapDrawable(context.getResources(),
|
||||
BitmapUtil.createScaledBitmap(context, masterSecret, getUri(), maxWidth, maxHeight));
|
||||
thumbnailCache.put(part.getDataUri(), new SoftReference<>(thumbnail));
|
||||
|
||||
return thumbnail;
|
||||
} catch (FileNotFoundException e) {
|
||||
@@ -183,11 +181,11 @@ public class ImageSlide extends Slide {
|
||||
return SmilUtil.createMediaElement("img", document, new String(getPart().getName()));
|
||||
}
|
||||
|
||||
private static PduPart constructPartFromUri(Context context, Uri uri)
|
||||
private static PduPart constructPartFromUri(Context context, MasterSecret masterSecret, Uri uri)
|
||||
throws IOException, BitmapDecodingException
|
||||
{
|
||||
PduPart part = new PduPart();
|
||||
byte[] data = BitmapUtil.createScaledBytes(context, uri, 1280, 1280, MAX_MESSAGE_SIZE);
|
||||
byte[] data = BitmapUtil.createScaledBytes(context, masterSecret, uri, 1280, 1280, MAX_MESSAGE_SIZE);
|
||||
|
||||
part.setData(data);
|
||||
part.setDataUri(uri);
|
||||
|
||||
@@ -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