optimizeImage method
Optimizes an image file using the given configuration.
Returns the optimized file, or null if optimization is not supported. Throws AssetOptException on failure.
Implementation
Future<File?> optimizeImage(
File image,
OptimizationConfig config, {
bool? hasAlpha,
}) async {
try {
final optimizedPath = '${image.path}.optimized';
final extension = p.extension(image.path).toLowerCase();
if (extension == '.svg') {
return SvgOptimizer().optimize(image, optimizedPath);
}
if (extension == '.webp') {
if (NativeOptimizer.hasCwebp) {
return NativeOptimizer.toWebp(image, optimizedPath, quality: config.webpQuality);
}
throw OptimizationSkippedException('WebP optimization skipped: cwebp not available');
}
File? optimizedFile;
if (config.resize == null) {
optimizedFile = await _tryNativeOptimization(
image,
optimizedPath,
extension,
hasAlpha ?? false,
config,
);
if (optimizedFile != null) {
return optimizedFile;
}
}
final bytes = await image.readAsBytes();
final originalImage = img.decodeImage(bytes);
if (originalImage == null) return null;
List<int> optimizedBytes;
switch (extension) {
case '.jpg':
case '.jpeg':
optimizedBytes = _optimizeJpeg(originalImage, config);
break;
case '.png':
optimizedBytes = _optimizePng(originalImage, config);
break;
case '.webp':
throw OptimizationSkippedException('WebP optimization requires cwebp');
default:
throw AssetOptException('Unsupported image type: $extension');
}
optimizedFile = File(optimizedPath);
await optimizedFile.writeAsBytes(optimizedBytes);
return optimizedFile;
} catch (e) {
throw AssetOptException('Failed to optimize image ${image.path}: $e');
}
}