Signal-Android/app/src/main/java/org/thoughtcrime/securesms/util/ImageCompressionUtil.java

131 wiersze
4.1 KiB
Java

package org.thoughtcrime.securesms.util;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import org.thoughtcrime.securesms.mms.GlideApp;
import java.io.ByteArrayOutputStream;
import java.util.concurrent.ExecutionException;
public final class ImageCompressionUtil {
private ImageCompressionUtil () {}
/**
* A result satisfying the provided constraints, or null if they could not be met.
*/
@WorkerThread
public static @Nullable Result compressWithinConstraints(@NonNull Context context,
@NonNull String mimeType,
@NonNull Object glideModel,
int maxDimension,
int maxBytes,
@IntRange(from = 0, to = 100) int quality)
throws BitmapDecodingException
{
Result result = compress(context, mimeType, glideModel, maxDimension, quality);
if (result.getData().length <= maxBytes) {
return result;
} else {
return null;
}
}
/**
* Compresses the image to match the requested parameters.
*/
@WorkerThread
public static @NonNull Result compress(@NonNull Context context,
@NonNull String mimeType,
@NonNull Object glideModel,
int maxDimension,
@IntRange(from = 0, to = 100) int quality)
throws BitmapDecodingException
{
Bitmap scaledBitmap;
try {
scaledBitmap = GlideApp.with(context.getApplicationContext())
.asBitmap()
.load(glideModel)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.centerInside()
.submit(maxDimension, maxDimension)
.get();
} catch (ExecutionException | InterruptedException e) {
throw new BitmapDecodingException(e);
}
if (scaledBitmap == null) {
throw new BitmapDecodingException("Unable to decode image");
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
Bitmap.CompressFormat format = mimeTypeToCompressFormat(mimeType);
scaledBitmap.compress(format, quality, output);
byte[] data = output.toByteArray();
return new Result(data, compressFormatToMimeType(format), scaledBitmap.getWidth(), scaledBitmap.getHeight());
}
private static @NonNull Bitmap.CompressFormat mimeTypeToCompressFormat(@NonNull String mimeType) {
if (MediaUtil.isJpegType(mimeType) || MediaUtil.isHeicType(mimeType) || MediaUtil.isHeifType(mimeType)) {
return Bitmap.CompressFormat.JPEG;
} else {
return Bitmap.CompressFormat.PNG;
}
}
private static @NonNull String compressFormatToMimeType(@NonNull Bitmap.CompressFormat format) {
switch (format) {
case JPEG:
return MediaUtil.IMAGE_JPEG;
case PNG:
return MediaUtil.IMAGE_PNG;
default:
throw new AssertionError("Unsupported format!");
}
}
public static final class Result {
private final byte[] data;
private final String mimeType;
private final int height;
private final int width;
public Result(@NonNull byte[] data, @NonNull String mimeType, int width, int height) {
this.data = data;
this.mimeType = mimeType;
this.width = width;
this.height = height;
}
public byte[] getData() {
return data;
}
public @NonNull String getMimeType() {
return mimeType;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
}