Merge pull request #23 from koji-1009/refactor/using
refactor: use JNI Arena for automatic resource management
This commit is contained in:
commit
d7ffa28265
|
|
@ -40,20 +40,13 @@ final class ImageConverterAndroid implements ImageConverterPlatform {
|
||||||
int quality = 100,
|
int quality = 100,
|
||||||
ResizeMode resizeMode = const OriginalResizeMode(),
|
ResizeMode resizeMode = const OriginalResizeMode(),
|
||||||
}) async {
|
}) async {
|
||||||
JByteArray? inputJBytes;
|
return using((arena) {
|
||||||
Bitmap? originalBitmap;
|
final inputJBytes = JByteArray.from(inputData)..releasedBy(arena);
|
||||||
Bitmap? scaledBitmap;
|
final originalBitmap = BitmapFactory.decodeByteArray(
|
||||||
Bitmap? bitmapToCompress;
|
|
||||||
Bitmap$CompressFormat? compressFormat;
|
|
||||||
ByteArrayOutputStream? outputStream;
|
|
||||||
JByteArray? outputJBytes;
|
|
||||||
try {
|
|
||||||
inputJBytes = JByteArray.from(inputData);
|
|
||||||
originalBitmap = BitmapFactory.decodeByteArray(
|
|
||||||
inputJBytes,
|
inputJBytes,
|
||||||
0,
|
0,
|
||||||
inputData.length,
|
inputData.length,
|
||||||
);
|
)?..releasedBy(arena);
|
||||||
if (originalBitmap == null) {
|
if (originalBitmap == null) {
|
||||||
throw const ImageDecodingException('Invalid image data.');
|
throw const ImageDecodingException('Invalid image data.');
|
||||||
}
|
}
|
||||||
|
|
@ -65,26 +58,24 @@ final class ImageConverterAndroid implements ImageConverterPlatform {
|
||||||
originalHeight,
|
originalHeight,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final Bitmap? bitmapToCompress;
|
||||||
if (newWidth == originalWidth && newHeight == originalHeight) {
|
if (newWidth == originalWidth && newHeight == originalHeight) {
|
||||||
bitmapToCompress = originalBitmap;
|
bitmapToCompress = originalBitmap;
|
||||||
} else {
|
} else {
|
||||||
scaledBitmap = Bitmap.createScaledBitmap(
|
bitmapToCompress = Bitmap.createScaledBitmap(
|
||||||
originalBitmap,
|
originalBitmap,
|
||||||
newWidth,
|
newWidth,
|
||||||
newHeight,
|
newHeight,
|
||||||
true, // filter
|
true, // filter
|
||||||
);
|
)?..releasedBy(arena);
|
||||||
bitmapToCompress = scaledBitmap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmapToCompress == null) {
|
if (bitmapToCompress == null) {
|
||||||
// This should not happen if originalBitmap is valid
|
|
||||||
throw const ImageConversionException(
|
throw const ImageConversionException(
|
||||||
'Bitmap could not be prepared for compression.',
|
'Bitmap could not be prepared for compression.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
compressFormat = switch (format) {
|
final compressFormat = switch (format) {
|
||||||
OutputFormat.jpeg => Bitmap$CompressFormat.JPEG,
|
OutputFormat.jpeg => Bitmap$CompressFormat.JPEG,
|
||||||
OutputFormat.png => Bitmap$CompressFormat.PNG,
|
OutputFormat.png => Bitmap$CompressFormat.PNG,
|
||||||
// TODO: WebP is deprecated since Android 10, consider using WebP_LOSSY or WebP_LOSSLESS
|
// TODO: WebP is deprecated since Android 10, consider using WebP_LOSSY or WebP_LOSSLESS
|
||||||
|
|
@ -92,9 +83,9 @@ final class ImageConverterAndroid implements ImageConverterPlatform {
|
||||||
OutputFormat.heic => throw UnsupportedError(
|
OutputFormat.heic => throw UnsupportedError(
|
||||||
'HEIC output format is not supported on Android.',
|
'HEIC output format is not supported on Android.',
|
||||||
),
|
),
|
||||||
};
|
}..releasedBy(arena);
|
||||||
|
|
||||||
outputStream = ByteArrayOutputStream();
|
final outputStream = ByteArrayOutputStream()..releasedBy(arena);
|
||||||
final success = bitmapToCompress.compress(
|
final success = bitmapToCompress.compress(
|
||||||
compressFormat,
|
compressFormat,
|
||||||
quality,
|
quality,
|
||||||
|
|
@ -104,7 +95,7 @@ final class ImageConverterAndroid implements ImageConverterPlatform {
|
||||||
throw ImageEncodingException(format, 'Failed to compress bitmap.');
|
throw ImageEncodingException(format, 'Failed to compress bitmap.');
|
||||||
}
|
}
|
||||||
|
|
||||||
outputJBytes = outputStream.toByteArray();
|
final outputJBytes = outputStream.toByteArray()?..releasedBy(arena);
|
||||||
if (outputJBytes == null) {
|
if (outputJBytes == null) {
|
||||||
throw ImageEncodingException(
|
throw ImageEncodingException(
|
||||||
format,
|
format,
|
||||||
|
|
@ -113,15 +104,6 @@ final class ImageConverterAndroid implements ImageConverterPlatform {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Uint8List.fromList(outputJBytes.toList());
|
return Uint8List.fromList(outputJBytes.toList());
|
||||||
} finally {
|
});
|
||||||
inputJBytes?.release();
|
|
||||||
originalBitmap?.recycle();
|
|
||||||
originalBitmap?.release();
|
|
||||||
scaledBitmap?.recycle();
|
|
||||||
scaledBitmap?.release();
|
|
||||||
compressFormat?.release();
|
|
||||||
outputStream?.release();
|
|
||||||
outputJBytes?.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue