optimizeImage method

Future<File?> optimizeImage(
  1. File image,
  2. OptimizationConfig config, {
  3. bool? hasAlpha,
})

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');
  }
}