compressImage static method
- {required File image,
- Compression? compression}
Compresses image
and stores the image at target
.
This method compresses the image at-least once and then keeps it compressing until Compression.maxFileSize is reached.
See also
Implementation
static Future<File?> compressImage({required File image, Compression? compression}) async {
File? compressedImage;
try {
compression ??= const Compression.standard();
final int maxFileSize = compression.maxFileSize;
final int originalSize = await image.length();
int quality = compression.quality;
if (kDebugMode) print('Size before compression : $originalSize');
compressedImage = image;
//tempFile for more compression if needed
final String dir = await zdsTempDirectory('compressed');
final String imageExt = compression.format == CompressFormat.jpeg
? 'jpeg'
: compression.format == CompressFormat.png
? 'png'
: path.extension(compressedImage.absolute.path).toLowerCase();
final String tmpName = 'TMP_${DateTime.now().microsecondsSinceEpoch}.$imageExt';
final File tempFile = File(path.join(dir, tmpName));
//targetFile
final File targetFile = File('$dir/${path.basenameWithoutExtension(image.absolute.path)}.$imageExt');
final ui.Image decodeImage = await decodeImageFromList(image.readAsBytesSync());
final double scaleFactor = decodeImage.height > decodeImage.width
? compression.minHeight / decodeImage.height
: compression.minWidth / decodeImage.width;
final int newHeight = (decodeImage.height * scaleFactor).toInt();
final int newWidth = (decodeImage.width * scaleFactor).toInt();
int compressedSize;
/// Compress at-least once
do {
if (targetFile.existsSync()) await targetFile.delete();
final XFile? processedFile = await FlutterImageCompress.compressAndGetFile(
compressedImage?.absolute.path ?? '',
autoCorrectionAngle: compression.autoCorrectionAngle,
format: compression.format,
inSampleSize: compression.inSampleSize,
keepExif: compression.keepExif,
minHeight: newHeight,
minWidth: newWidth,
numberOfRetries: compression.numberOfRetries,
quality: quality,
rotate: compression.rotate,
targetFile.absolute.path,
);
// Return if compression failed
if (processedFile == null) throw PlatformException(code: 'PROCESS_ERR');
//delete existing compressed file
if (tempFile.existsSync()) await tempFile.delete();
compressedImage = await File(processedFile.path).copy(tempFile.path);
compressedSize = await compressedImage.length();
if (compressedSize > originalSize) throw PlatformException(code: 'COMPRESS_ERR');
if (kDebugMode) print('quality after compression $quality : $compressedSize');
quality = quality - 5;
} while (quality >= 50 && compressedSize >= maxFileSize);
return targetFile;
} catch (e) {
if (kDebugMode) print(e);
rethrow;
} finally {
await compressedImage?.delete();
}
}