compressImageBuffer method
Compresses an image buffer to fit within a maximum byte size.
Implementation
Future<CompressedImageResult> compressImageBuffer(
Uint8List imageBuffer, {
int maxBytes = imageTargetRawSize,
String? originalMediaType,
}) async {
final fallbackFormat = originalMediaType?.split('/').last ?? 'jpeg';
final normalizedFallback = fallbackFormat == 'jpg'
? 'jpeg'
: fallbackFormat;
if (imageBuffer.length <= maxBytes) {
return CompressedImageResult(
base64: base64Encode(imageBuffer),
mediaType: 'image/$normalizedFallback',
originalSize: imageBuffer.length,
);
}
if (_imageProcessor == null || _getImageMetadata == null) {
throw ImageResizeError(
'Unable to compress image (${formatFileSize(imageBuffer.length)}) '
'to fit within ${formatFileSize(maxBytes)}. Image processor not configured.',
);
}
try {
final metadata = await _getImageMetadata!(imageBuffer);
final format = metadata.format ?? normalizedFallback;
// Try progressive resizing with format preservation
for (final scalingFactor in [1.0, 0.75, 0.5, 0.25]) {
final newWidth = ((metadata.width ?? 2000) * scalingFactor).round();
final newHeight = ((metadata.height ?? 2000) * scalingFactor).round();
final resized = await _imageProcessor!(
imageBuffer,
width: newWidth,
height: newHeight,
format: format,
quality: format == 'jpeg' || format == 'webp' ? 80 : null,
compressionLevel: format == 'png' ? 9 : null,
palette: format == 'png' ? true : null,
);
if (resized.length <= maxBytes) {
return CompressedImageResult(
base64: base64Encode(resized),
mediaType: 'image/$format',
originalSize: imageBuffer.length,
);
}
}
// Try JPEG with moderate compression
final jpegBuffer = await _imageProcessor!(
imageBuffer,
width: 600,
height: 600,
format: 'jpeg',
quality: 50,
);
if (jpegBuffer.length <= maxBytes) {
return CompressedImageResult(
base64: base64Encode(jpegBuffer),
mediaType: 'image/jpeg',
originalSize: imageBuffer.length,
);
}
// Ultra-compressed JPEG
final ultraCompressed = await _imageProcessor!(
imageBuffer,
width: 400,
height: 400,
format: 'jpeg',
quality: 20,
);
return CompressedImageResult(
base64: base64Encode(ultraCompressed),
mediaType: 'image/jpeg',
originalSize: imageBuffer.length,
);
} catch (error) {
_logError(error);
if (imageBuffer.length <= maxBytes) {
final detected = detectImageFormatFromBuffer(imageBuffer);
return CompressedImageResult(
base64: base64Encode(imageBuffer),
mediaType: detected.value,
originalSize: imageBuffer.length,
);
}
throw ImageResizeError(
'Unable to compress image (${formatFileSize(imageBuffer.length)}) '
'to fit within ${formatFileSize(maxBytes)}. Please use a smaller image.',
);
}
}