Repository: FlutterGen/flutter_gen

Issue:
[FR]: Parse meta data for images with animation
### Is there an existing issue for this?

- [x] I have searched the existing issues

### Describe the problem

Besides image sizes, I want to read more metadata from animated images like GIF and WebP, e.g. frame count, animation duration, etc. As parsing animation files at runtime is relatively expensive, it would be great if `flutter_gen` can parse this information for me.

### Describe the solution

Add a new optional option `parse_animation` in config. If it's true, `flutter_gen` should parse animated images and write parsed information in `AssetGenImage`.

### Additional context

_No response_

### Code of Conduct

- [x] I agree to follow this project's Code of Conduct



Fix patch:
diff --git a/README.md b/README.md
index 3c9dfa6f0..163f12840 100644
--- a/README.md
+++ b/README.md
@@ -135,7 +135,7 @@ fluttergen -c example/pubspec.yaml
 ## Configuration file
 
 [FlutterGen] generates dart files based on the key **`flutter`** and **`flutter_gen`** of [`pubspec.yaml`](https://dart.dev/tools/pub/pubspec).  
-Default configuration can be found [here](https://github.com/FlutterGen/flutter_gen/tree/main/packages/core/lib/settings/config_default.dart). 
+Default configuration can be found [here](https://github.com/FlutterGen/flutter_gen/tree/main/packages/core/lib/settings/config_default.dart).
 
 ```yaml
 # pubspec.yaml
@@ -173,7 +173,6 @@ flutter:
 
 You can also configure generate options in the `build.yaml`, it will be read before the `pubspec.yaml` if it exists.
 
-
 ```yaml
 # build.yaml
 # ...
@@ -279,7 +278,9 @@ Widget build(BuildContext context) {
   );
 }
 ```
+
 or
+
 ```dart
 // Explicit usage for `Image`/`SvgPicture`/`Lottie`.
 Widget build(BuildContext context) {
@@ -343,6 +344,32 @@ Widget build(BuildContext context) {
 }
 ```
 
+You can use `parse_animation` to generate more animation details.
+It will automatically parse all animation information for GIF and WebP files,
+including frames, duration, etc. As this option significantly increases generation time,
+The option is disabled by default; enabling it will significantly increase the generation elapse.
+
+```yaml
+flutter_gen:
+  images:
+    parse_animation: true # <- Add this line (default: false)
+    # This option implies parse_metadata: true when parsing images.
+```
+
+For GIF and WebP animation, several new nullable field is added to the
+generated class. For example:
+
+```dart
+AssetGenImage get animated => 
+  const AssetGenImage(
+    'assets/images/animated.webp',
+    size: Size(209.0, 49.0),
+    isAnimation: true,
+    duration: Duration(milliseconds: 1000),
+    frames: 15,
+  );
+```
+
 #### Usage Example
 
 [FlutterGen] generates [Image](https://api.flutter.dev/flutter/widgets/Image-class.html) class if the asset is Flutter supported image format.
@@ -581,7 +608,9 @@ Plugin issues that are not specific to [FlutterGen] can be filed in the [Flutter
 ### Known Issues
 
 #### Bad State: No Element when using build_runner
+
 If you get an error message like this:
+
 ```
 [SEVERE] flutter_gen_runner:flutter_gen_runner on $package$:
 
@@ -620,8 +649,6 @@ output-localization-file: app_localizations.dart
 synthetic-package: false <--- ⚠️Add this line⚠️
 ```
 
-If you get 
-
 ## Contributing
 
 **We are looking for co-developers.**
diff --git a/examples/example/lib/gen/assets.gen.dart b/examples/example/lib/gen/assets.gen.dart
index 47177703e..e463d1346 100644
--- a/examples/example/lib/gen/assets.gen.dart
+++ b/examples/example/lib/gen/assets.gen.dart
@@ -242,12 +242,14 @@ class AssetGenImage {
     this._assetName, {
     this.size,
     this.flavors = const {},
+    this.animation,
   });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -318,6 +320,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
diff --git a/examples/example_resources/lib/gen/assets.gen.dart b/examples/example_resources/lib/gen/assets.gen.dart
index 1d189ad35..bc83feb14 100644
--- a/examples/example_resources/lib/gen/assets.gen.dart
+++ b/examples/example_resources/lib/gen/assets.gen.dart
@@ -70,6 +70,7 @@ class AssetGenImage {
     this._assetName, {
     this.size,
     this.flavors = const {},
+    this.animation,
   });
 
   final String _assetName;
@@ -78,6 +79,7 @@ class AssetGenImage {
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -150,6 +152,18 @@ class AssetGenImage {
   String get keyName => 'packages/example_resources/$_assetName';
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
diff --git a/packages/command/pubspec.yaml b/packages/command/pubspec.yaml
index 886d67cfc..72a4b9644 100644
--- a/packages/command/pubspec.yaml
+++ b/packages/command/pubspec.yaml
@@ -14,6 +14,7 @@ executables:
 
 dependencies:
   flutter_gen_core: 5.10.0
+
   args: ^2.0.0
   logging: ^1.3.0
 
diff --git a/packages/core/lib/generators/assets_generator.dart b/packages/core/lib/generators/assets_generator.dart
index 26944f1ea..8194425f9 100644
--- a/packages/core/lib/generators/assets_generator.dart
+++ b/packages/core/lib/generators/assets_generator.dart
@@ -63,6 +63,7 @@ Future<String> generateAssets(
       ImageIntegration(
         config.packageParameterLiteral,
         parseMetadata: config.flutterGen.parseMetadata,
+        parseAnimation: config.flutterGen.images.parseAnimation,
       ),
     if (config.flutterGen.integrations.flutterSvg)
       SvgIntegration(
diff --git a/packages/core/lib/generators/integrations/image_integration.dart b/packages/core/lib/generators/integrations/image_integration.dart
index d1c422dab..ed5a73e91 100644
--- a/packages/core/lib/generators/integrations/image_integration.dart
+++ b/packages/core/lib/generators/integrations/image_integration.dart
@@ -2,6 +2,7 @@ import 'dart:io';
 
 import 'package:flutter_gen_core/generators/integrations/integration.dart';
 import 'package:flutter_gen_core/utils/log.dart';
+import 'package:image/image.dart' as img;
 import 'package:image_size_getter/file_input.dart';
 import 'package:image_size_getter/image_size_getter.dart';
 
@@ -12,9 +13,12 @@ import 'package:image_size_getter/image_size_getter.dart';
 class ImageIntegration extends Integration {
   ImageIntegration(
     String packageName, {
-    super.parseMetadata,
+    required super.parseMetadata,
+    required this.parseAnimation,
   }) : super(packageName);
 
+  final bool parseAnimation;
+
   String get packageParameter => isPackage ? ' = package' : '';
 
   String get keyName =>
@@ -33,6 +37,7 @@ class ImageIntegration extends Integration {
     this._assetName, {
     this.size,
     this.flavors = const {},
+    this.animation,
   });
 
   final String _assetName;
@@ -41,6 +46,7 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -110,6 +116,18 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   String get keyName => $keyName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
 ''';
 
   @override
@@ -117,12 +135,22 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
 
   @override
   String classInstantiate(AssetType asset) {
-    final info = parseMetadata ? _getMetadata(asset) : null;
+    final info = parseMetadata || parseAnimation ? _getMetadata(asset) : null;
     final buffer = StringBuffer(className);
     buffer.write('(');
     buffer.write('\'${asset.posixStylePath}\'');
     if (info != null) {
-      buffer.write(', size: Size(${info.width}, ${info.height})');
+      buffer.write(', size: const Size(${info.width}, ${info.height})');
+
+      if (info.animation case final animation?) {
+        buffer.write(', animation: const AssetGenImageAnimation(');
+        buffer.write('isAnimation: ${animation.frames > 1}');
+        buffer.write(
+          ', duration: Duration(milliseconds: ${animation.duration.inMilliseconds})',
+        );
+        buffer.write(', frames: ${animation.frames}');
+        buffer.write(')');
+      }
     }
     if (asset.flavors.isNotEmpty) {
       buffer.write(', flavors: {');
@@ -162,10 +190,53 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
         FileInput(File(asset.fullPath)),
       );
       final size = result.size;
-      return ImageMetadata(size.width.toDouble(), size.height.toDouble());
+      final animation = parseAnimation ? _parseAnimation(asset) : null;
+
+      return ImageMetadata(
+        width: size.width.toDouble(),
+        height: size.height.toDouble(),
+        animation: animation,
+      );
     } catch (e, s) {
       log.warning('Failed to parse \'${asset.path}\' metadata.', e, s);
     }
     return null;
   }
+
+  ImageAnimation? _parseAnimation(AssetType asset) {
+    try {
+      final decoder = switch (asset.mime) {
+        'image/gif' => img.GifDecoder(),
+        'image/webp' => img.WebPDecoder(),
+        _ => null,
+      };
+
+      if (decoder == null) {
+        return null;
+      }
+
+      final file = File(asset.fullPath);
+      final bytes = file.readAsBytesSync();
+      final image = decoder.decode(bytes);
+
+      if (image == null) {
+        return null;
+      }
+
+      return ImageAnimation(
+        frames: image.frames.length,
+        duration: Duration(
+          milliseconds: image.frames.fold(
+            0,
+            (duration, frame) => duration + frame.frameDuration,
+          ),
+        ),
+      );
+    } catch (e) {
+      stderr.writeln(
+        '[WARNING] Failed to parse \'${asset.path}\' animation information: $e',
+      );
+    }
+    return null;
+  }
 }
diff --git a/packages/core/lib/generators/integrations/integration.dart b/packages/core/lib/generators/integrations/integration.dart
index b3c0dcff3..d6ddc8308 100644
--- a/packages/core/lib/generators/integrations/integration.dart
+++ b/packages/core/lib/generators/integrations/integration.dart
@@ -55,8 +55,24 @@ const String deprecationMessagePackage =
 /// Currently only contains the width and height, but could contain more in
 /// future.
 class ImageMetadata {
-  const ImageMetadata(this.width, this.height);
+  const ImageMetadata({
+    required this.width,
+    required this.height,
+    this.animation,
+  });
 
   final double width;
   final double height;
+  final ImageAnimation? animation;
+}
+
+/// Metadata about the parsed animation file when [parseAnimation] is true.
+class ImageAnimation {
+  const ImageAnimation({
+    required this.frames,
+    required this.duration,
+  });
+
+  final int frames;
+  final Duration duration;
 }
diff --git a/packages/core/lib/generators/integrations/svg_integration.dart b/packages/core/lib/generators/integrations/svg_integration.dart
index 49087cb21..86919d88a 100644
--- a/packages/core/lib/generators/integrations/svg_integration.dart
+++ b/packages/core/lib/generators/integrations/svg_integration.dart
@@ -5,8 +5,10 @@ import 'package:flutter_gen_core/utils/log.dart';
 import 'package:vector_graphics_compiler/vector_graphics_compiler.dart';
 
 class SvgIntegration extends Integration {
-  SvgIntegration(String packageName, {super.parseMetadata})
-      : super(packageName);
+  SvgIntegration(
+    String packageName, {
+    super.parseMetadata,
+  }) : super(packageName);
 
   String get packageExpression => isPackage ? ' = package' : '';
 
@@ -138,7 +140,10 @@ ${isPackage ? "\n  static const String package = '$packageName';" : ''}
       // but it's also the same way it will be eventually rendered by Flutter.
       final svg = File(asset.fullPath).readAsStringSync();
       final vec = parseWithoutOptimizers(svg);
-      return ImageMetadata(vec.width, vec.height);
+      return ImageMetadata(
+        width: vec.width,
+        height: vec.height,
+      );
     } catch (e, s) {
       log.warning('Failed to parse SVG \'${asset.path}\' metadata.', e, s);
       return null;
diff --git a/packages/core/lib/settings/config_default.dart b/packages/core/lib/settings/config_default.dart
index 0f765da3d..882649da6 100644
--- a/packages/core/lib/settings/config_default.dart
+++ b/packages/core/lib/settings/config_default.dart
@@ -12,6 +12,10 @@ flutter_gen:
     flutter_svg: false
     rive: false
     lottie: false
+  
+  images:
+    # Optional
+    parse_animation: false
 
   assets:
     enabled: true # Optional
diff --git a/packages/core/lib/settings/pubspec.dart b/packages/core/lib/settings/pubspec.dart
index 5732ef74b..a8d90afa9 100644
--- a/packages/core/lib/settings/pubspec.dart
+++ b/packages/core/lib/settings/pubspec.dart
@@ -103,6 +103,7 @@ class FlutterGen {
     required this.output,
     required this.lineLength,
     required this.parseMetadata,
+    required this.images,
     required this.assets,
     required this.fonts,
     required this.integrations,
@@ -120,6 +121,9 @@ class FlutterGen {
   @JsonKey(name: 'parse_metadata', required: true)
   final bool parseMetadata;
 
+  @JsonKey(name: 'images', required: true)
+  final FlutterGenImages images;
+
   @JsonKey(name: 'assets', required: true)
   final FlutterGenAssets assets;
 
@@ -185,6 +189,19 @@ class FlutterGenAssets {
   final List<String> exclude;
 }
 
+@JsonSerializable()
+class FlutterGenImages {
+  const FlutterGenImages({
+    required this.parseAnimation,
+  });
+
+  factory FlutterGenImages.fromJson(Map json) =>
+      _$FlutterGenImagesFromJson(json);
+
+  @JsonKey(name: 'parse_animation', required: true)
+  final bool parseAnimation;
+}
+
 @JsonSerializable()
 class FlutterGenFonts {
   const FlutterGenFonts({
diff --git a/packages/core/lib/settings/pubspec.g.dart b/packages/core/lib/settings/pubspec.g.dart
index 93fe1742d..a72beec85 100644
--- a/packages/core/lib/settings/pubspec.g.dart
+++ b/packages/core/lib/settings/pubspec.g.dart
@@ -74,6 +74,7 @@ FlutterGen _$FlutterGenFromJson(Map json) => $checkedCreate(
             'output',
             'line_length',
             'parse_metadata',
+            'images',
             'assets',
             'fonts',
             'integrations',
@@ -82,6 +83,7 @@ FlutterGen _$FlutterGenFromJson(Map json) => $checkedCreate(
           requiredKeys: const [
             'output',
             'parse_metadata',
+            'images',
             'assets',
             'fonts',
             'integrations',
@@ -93,6 +95,8 @@ FlutterGen _$FlutterGenFromJson(Map json) => $checkedCreate(
           lineLength:
               $checkedConvert('line_length', (v) => (v as num?)?.toInt()),
           parseMetadata: $checkedConvert('parse_metadata', (v) => v as bool),
+          images: $checkedConvert(
+              'images', (v) => FlutterGenImages.fromJson(v as Map)),
           assets: $checkedConvert(
               'assets', (v) => FlutterGenAssets.fromJson(v as Map)),
           fonts: $checkedConvert(
@@ -162,6 +166,23 @@ FlutterGenAssets _$FlutterGenAssetsFromJson(Map json) => $checkedCreate(
       },
     );
 
+FlutterGenImages _$FlutterGenImagesFromJson(Map json) => $checkedCreate(
+      'FlutterGenImages',
+      json,
+      ($checkedConvert) {
+        $checkKeys(
+          json,
+          allowedKeys: const ['parse_animation'],
+          requiredKeys: const ['parse_animation'],
+        );
+        final val = FlutterGenImages(
+          parseAnimation: $checkedConvert('parse_animation', (v) => v as bool),
+        );
+        return val;
+      },
+      fieldKeyMap: const {'parseAnimation': 'parse_animation'},
+    );
+
 FlutterGenFonts _$FlutterGenFontsFromJson(Map json) => $checkedCreate(
       'FlutterGenFonts',
       json,
diff --git a/packages/core/lib/version.gen.dart b/packages/core/lib/version.gen.dart
index e0a6a78d0..a5c517119 100644
--- a/packages/core/lib/version.gen.dart
+++ b/packages/core/lib/version.gen.dart
@@ -1,2 +1,2 @@
 /// DO NOT MODIFY BY HAND, Generated by version_gen
-String packageVersion = '5.10.0';
+String packageVersion = '5.11.0';
diff --git a/packages/core/pubspec.yaml b/packages/core/pubspec.yaml
index f49bf3ce5..70a83bb6a 100644
--- a/packages/core/pubspec.yaml
+++ b/packages/core/pubspec.yaml
@@ -16,7 +16,7 @@ dependencies:
   meta: ^1.7.0
   path: ^1.8.0
   yaml: ^3.0.0
-  mime: '>=1.0.0 <3.0.0'
+  mime: ">=1.0.0 <3.0.0"
   xml: ^6.0.0
   dartx: ^1.0.0
   color: ^3.0.0
@@ -26,11 +26,12 @@ dependencies:
   logging: ^1.3.0
 
   dart_style: ^3.0.0
-  archive: '>=3.4.0 <5.0.0'
+  archive: ">=3.4.0 <5.0.0"
   args: ^2.0.0
   pub_semver: ^2.0.0
   vector_graphics_compiler: ^1.1.9
   image_size_getter: ^2.4.0
+  image: ^4.5.4
 
 dev_dependencies:
   lints: any # Ignoring the version to allow editing across SDK versions.
diff --git a/packages/runner/lib/flutter_gen_runner.dart b/packages/runner/lib/flutter_gen_runner.dart
index e46d58e52..410fc0020 100644
--- a/packages/runner/lib/flutter_gen_runner.dart
+++ b/packages/runner/lib/flutter_gen_runner.dart
@@ -34,39 +34,39 @@ class FlutterGenBuilder extends Builder {
 
   @override
   Future<void> build(BuildStep buildStep) async {
-    if (_config == null) {
-      return;
-    }
-    final state = await _createState(_config, buildStep);
-    if (state.shouldSkipGenerate(_currentState)) {
-      return;
+    if (_config case final config?) {
+      final state = await _createState(config, buildStep);
+      if (state.shouldSkipGenerate(_currentState)) {
+        return;
+      }
+      _currentState = state;
+
+      await generator.build(
+        config: config,
+        writer: (contents, path) {
+          buildStep.writeAsString(_output(buildStep, path), contents);
+        },
+      );
     }
-    _currentState = state;
-
-    await generator.build(
-      config: _config,
-      writer: (contents, path) {
-        buildStep.writeAsString(_output(buildStep, path), contents);
-      },
-    );
   }
 
   @override
   Map<String, List<String>> get buildExtensions {
-    if (_config == null) {
+    if (_config case final config?) {
+      final output = config.pubspec.flutterGen.output;
+      return {
+        r'$package$': [
+          for (final name in [
+            generator.assetsName,
+            generator.colorsName,
+            generator.fontsName,
+          ])
+            join(output, name),
+        ],
+      };
+    } else {
       return {};
     }
-    final output = _config.pubspec.flutterGen.output;
-    return {
-      r'$package$': [
-        for (final name in [
-          generator.assetsName,
-          generator.colorsName,
-          generator.fontsName,
-        ])
-          join(output, name),
-      ],
-    };
   }
 
   Future<_FlutterGenBuilderState> _createState(


Test patch:
diff --git a/packages/core/test_resources/actual_data/assets_assets.gen.dart b/packages/core/test_resources/actual_data/assets_assets.gen.dart
index c7de4f8bc..a1cde1318 100644
--- a/packages/core/test_resources/actual_data/assets_assets.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets.gen.dart
@@ -164,12 +164,14 @@ class AssetGenImage {
     this._assetName, {
     this.size,
     this.flavors = const {},
+    this.animation,
   });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -240,6 +242,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
diff --git a/packages/core/test_resources/actual_data/assets_assets_camel_case.gen.dart b/packages/core/test_resources/actual_data/assets_assets_camel_case.gen.dart
index c97a1d68f..b80406ae8 100644
--- a/packages/core/test_resources/actual_data/assets_assets_camel_case.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_camel_case.gen.dart
@@ -92,12 +92,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -160,3 +166,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/assets_assets_change_class_name.gen.dart b/packages/core/test_resources/actual_data/assets_assets_change_class_name.gen.dart
index 4ad5c9094..4e550ed85 100644
--- a/packages/core/test_resources/actual_data/assets_assets_change_class_name.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_change_class_name.gen.dart
@@ -48,12 +48,18 @@ class MyAssets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -116,3 +122,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart b/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart
index 6b9b4d5c8..101e180d9 100644
--- a/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_directory_path.gen.dart
@@ -80,12 +80,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -149,6 +155,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
     : _isVecFormat = false;
diff --git a/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart b/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart
index d293d5de1..5f0a74f20 100644
--- a/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_directory_path_with_package_parameter.gen.dart
@@ -83,7 +83,12 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
@@ -91,6 +96,7 @@ class AssetGenImage {
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -159,6 +165,18 @@ class AssetGenImage {
   String get keyName => 'packages/test/$_assetName';
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
     : _isVecFormat = false;
diff --git a/packages/core/test_resources/actual_data/assets_assets_exclude_files.gen.dart b/packages/core/test_resources/actual_data/assets_assets_exclude_files.gen.dart
index 43af0f0a3..da20c4edb 100644
--- a/packages/core/test_resources/actual_data/assets_assets_exclude_files.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_exclude_files.gen.dart
@@ -73,12 +73,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -141,3 +147,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart b/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart
index 09485c80e..41fdff25b 100644
--- a/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_flavored.gen.dart
@@ -165,12 +165,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -234,6 +240,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
     : _isVecFormat = false;
diff --git a/packages/core/test_resources/actual_data/assets_assets_no_integrations.gen.dart b/packages/core/test_resources/actual_data/assets_assets_no_integrations.gen.dart
index 18526b108..0eb1bd031 100644
--- a/packages/core/test_resources/actual_data/assets_assets_no_integrations.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_no_integrations.gen.dart
@@ -123,12 +123,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -191,3 +197,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart b/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart
index 3a9dc248b..1380d5d94 100644
--- a/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_package_parameter.gen.dart
@@ -71,7 +71,12 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
@@ -79,6 +84,7 @@ class AssetGenImage {
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -147,6 +153,18 @@ class AssetGenImage {
   String get keyName => 'packages/test/$_assetName';
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
     : _isVecFormat = false;
diff --git a/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart b/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart
index afdfe1c6f..6401e75e8 100644
--- a/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_package_parameter_disable_null_safety.gen.dart
@@ -59,7 +59,12 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
@@ -67,6 +72,7 @@ class AssetGenImage {
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -135,6 +141,18 @@ class AssetGenImage {
   String get keyName => 'packages/test/$_assetName';
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
     : _isVecFormat = false;
diff --git a/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart b/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart
index 951c8226d..a7da943ff 100644
--- a/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_parse_metadata.gen.dart
@@ -19,7 +19,7 @@ class $PicturesGen {
 
   /// File path: pictures/chip5.jpg
   AssetGenImage get chip5 =>
-      const AssetGenImage('pictures/chip5.jpg', size: Size(600.0, 403.0));
+      const AssetGenImage('pictures/chip5.jpg', size: const Size(600.0, 403.0));
 
   /// List of all assets
   List<AssetGenImage> get values => [chip5];
@@ -38,9 +38,14 @@ class $AssetsFlareGen {
 class $AssetsImagesGen {
   const $AssetsImagesGen();
 
+  /// Directory path: assets/images/animated
+  $AssetsImagesAnimatedGen get animated => const $AssetsImagesAnimatedGen();
+
   /// File path: assets/images/chip1.jpg
-  AssetGenImage get chip1 =>
-      const AssetGenImage('assets/images/chip1.jpg', size: Size(600.0, 403.0));
+  AssetGenImage get chip1 => const AssetGenImage(
+    'assets/images/chip1.jpg',
+    size: const Size(600.0, 403.0),
+  );
 
   /// File path: assets/images/chip2.jpg
   AssetGenImage get chip2 => const AssetGenImage('assets/images/chip2.jpg');
@@ -55,8 +60,10 @@ class $AssetsImagesGen {
   $AssetsImagesIconsGen get icons => const $AssetsImagesIconsGen();
 
   /// File path: assets/images/logo.png
-  AssetGenImage get logo =>
-      const AssetGenImage('assets/images/logo.png', size: Size(209.0, 49.0));
+  AssetGenImage get logo => const AssetGenImage(
+    'assets/images/logo.png',
+    size: const Size(209.0, 49.0),
+  );
 
   /// File path: assets/images/profile.jpg
   AssetGenImage get profileJpg =>
@@ -109,13 +116,31 @@ class $AssetsUnknownGen {
   List<String> get values => [unknownMimeType];
 }
 
+class $AssetsImagesAnimatedGen {
+  const $AssetsImagesAnimatedGen();
+
+  /// File path: assets/images/animated/emoji_hugging_face.webp
+  AssetGenImage get emojiHuggingFace => const AssetGenImage(
+    'assets/images/animated/emoji_hugging_face.webp',
+    size: const Size(512.0, 512.0),
+    animation: const AssetGenImageAnimation(
+      isAnimation: true,
+      duration: Duration(milliseconds: 2970),
+      frames: 45,
+    ),
+  );
+
+  /// List of all assets
+  List<AssetGenImage> get values => [emojiHuggingFace];
+}
+
 class $AssetsImagesChip3Gen {
   const $AssetsImagesChip3Gen();
 
   /// File path: assets/images/chip3/chip3.jpg
   AssetGenImage get chip3 => const AssetGenImage(
     'assets/images/chip3/chip3.jpg',
-    size: Size(600.0, 403.0),
+    size: const Size(600.0, 403.0),
   );
 
   /// List of all assets
@@ -128,7 +153,7 @@ class $AssetsImagesChip4Gen {
   /// File path: assets/images/chip4/chip4.jpg
   AssetGenImage get chip4 => const AssetGenImage(
     'assets/images/chip4/chip4.jpg',
-    size: Size(600.0, 403.0),
+    size: const Size(600.0, 403.0),
   );
 
   /// List of all assets
@@ -182,12 +207,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -251,6 +282,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
     : _isVecFormat = false;
diff --git a/packages/core/test_resources/actual_data/assets_assets_snake_case.gen.dart b/packages/core/test_resources/actual_data/assets_assets_snake_case.gen.dart
index 0a13edb4c..5dfbfe2be 100644
--- a/packages/core/test_resources/actual_data/assets_assets_snake_case.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_assets_snake_case.gen.dart
@@ -93,12 +93,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -161,3 +167,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/assets_change_output_path.gen.dart b/packages/core/test_resources/actual_data/assets_change_output_path.gen.dart
index fba2ca3c1..866ca6657 100644
--- a/packages/core/test_resources/actual_data/assets_change_output_path.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_change_output_path.gen.dart
@@ -48,12 +48,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -116,3 +122,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/assets_exclude_files.gen.dart b/packages/core/test_resources/actual_data/assets_exclude_files.gen.dart
new file mode 100644
index 000000000..4537d5b23
--- /dev/null
+++ b/packages/core/test_resources/actual_data/assets_exclude_files.gen.dart
@@ -0,0 +1,151 @@
+/// GENERATED CODE - DO NOT MODIFY BY HAND
+/// *****************************************************
+///  FlutterGen
+/// *****************************************************
+
+// coverage:ignore-file
+// ignore_for_file: type=lint
+// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use
+
+import 'package:flutter/widgets.dart';
+
+class $PicturesGen {
+  const $PicturesGen();
+
+  /// File path: pictures/chip5.jpg
+  AssetGenImage get chip5 => const AssetGenImage('pictures/chip5.jpg');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip5];
+}
+
+class $AssetsImagesGen {
+  const $AssetsImagesGen();
+
+  /// File path: assets/images/chip1.jpg
+  AssetGenImage get chip1 => const AssetGenImage('assets/images/chip1.jpg');
+
+  /// File path: assets/images/chip2.jpg
+  AssetGenImage get chip2 => const AssetGenImage('assets/images/chip2.jpg');
+
+  /// Directory path: assets/images/chip4
+  $AssetsImagesChip4Gen get chip4 => const $AssetsImagesChip4Gen();
+
+  /// File path: assets/images/profile.jpg
+  AssetGenImage get profile => const AssetGenImage('assets/images/profile.jpg');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip1, chip2, profile];
+}
+
+class $AssetsJsonGen {
+  const $AssetsJsonGen();
+
+  /// File path: assets/json/list.json
+  String get list => 'assets/json/list.json';
+
+  /// File path: assets/json/map.json
+  String get map => 'assets/json/map.json';
+
+  /// List of all assets
+  List<String> get values => [list, map];
+}
+
+class $AssetsImagesChip4Gen {
+  const $AssetsImagesChip4Gen();
+
+  /// File path: assets/images/chip4/chip4.jpg
+  AssetGenImage get chip4 =>
+      const AssetGenImage('assets/images/chip4/chip4.jpg');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip4];
+}
+
+class Assets {
+  const Assets._();
+
+  static const $AssetsImagesGen images = $AssetsImagesGen();
+  static const $AssetsJsonGen json = $AssetsJsonGen();
+  static const $PicturesGen pictures = $PicturesGen();
+}
+
+class AssetGenImage {
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.isAnimation = false,
+    this.duration = Duration.zero,
+    this.frames = 1,
+  });
+
+  final String _assetName;
+
+  final Size? size;
+  final Set<String> flavors;
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+
+  Image image({
+    Key? key,
+    AssetBundle? bundle,
+    ImageFrameBuilder? frameBuilder,
+    ImageErrorWidgetBuilder? errorBuilder,
+    String? semanticLabel,
+    bool excludeFromSemantics = false,
+    double? scale,
+    double? width,
+    double? height,
+    Color? color,
+    Animation<double>? opacity,
+    BlendMode? colorBlendMode,
+    BoxFit? fit,
+    AlignmentGeometry alignment = Alignment.center,
+    ImageRepeat repeat = ImageRepeat.noRepeat,
+    Rect? centerSlice,
+    bool matchTextDirection = false,
+    bool gaplessPlayback = true,
+    bool isAntiAlias = false,
+    String? package,
+    FilterQuality filterQuality = FilterQuality.medium,
+    int? cacheWidth,
+    int? cacheHeight,
+  }) {
+    return Image.asset(
+      _assetName,
+      key: key,
+      bundle: bundle,
+      frameBuilder: frameBuilder,
+      errorBuilder: errorBuilder,
+      semanticLabel: semanticLabel,
+      excludeFromSemantics: excludeFromSemantics,
+      scale: scale,
+      width: width,
+      height: height,
+      color: color,
+      opacity: opacity,
+      colorBlendMode: colorBlendMode,
+      fit: fit,
+      alignment: alignment,
+      repeat: repeat,
+      centerSlice: centerSlice,
+      matchTextDirection: matchTextDirection,
+      gaplessPlayback: gaplessPlayback,
+      isAntiAlias: isAntiAlias,
+      package: package,
+      filterQuality: filterQuality,
+      cacheWidth: cacheWidth,
+      cacheHeight: cacheHeight,
+    );
+  }
+
+  ImageProvider provider({AssetBundle? bundle, String? package}) {
+    return AssetImage(_assetName, bundle: bundle, package: package);
+  }
+
+  String get path => _assetName;
+
+  String get keyName => _assetName;
+}
diff --git a/packages/core/test_resources/actual_data/assets_normal.gen.dart b/packages/core/test_resources/actual_data/assets_normal.gen.dart
index ec34a2f84..2f35d2dc4 100644
--- a/packages/core/test_resources/actual_data/assets_normal.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_normal.gen.dart
@@ -128,12 +128,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -197,6 +203,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
     : _isVecFormat = false;
diff --git a/packages/core/test_resources/actual_data/assets_only_flutter_value.gen.dart b/packages/core/test_resources/actual_data/assets_only_flutter_value.gen.dart
index fba2ca3c1..866ca6657 100644
--- a/packages/core/test_resources/actual_data/assets_only_flutter_value.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_only_flutter_value.gen.dart
@@ -48,12 +48,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -116,3 +122,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/assets_package_parameter_disable_null_safety.gen.dart b/packages/core/test_resources/actual_data/assets_package_parameter_disable_null_safety.gen.dart
new file mode 100644
index 000000000..62267c8de
--- /dev/null
+++ b/packages/core/test_resources/actual_data/assets_package_parameter_disable_null_safety.gen.dart
@@ -0,0 +1,218 @@
+/// GENERATED CODE - DO NOT MODIFY BY HAND
+/// *****************************************************
+///  FlutterGen
+/// *****************************************************
+
+// coverage:ignore-file
+// ignore_for_file: type=lint
+// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use
+
+import 'package:flutter/services.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_svg/flutter_svg.dart' as _svg;
+import 'package:vector_graphics/vector_graphics.dart' as _vg;
+
+class $AssetsImagesGen {
+  const $AssetsImagesGen();
+
+  /// Directory path: assets/images/chip3
+  $AssetsImagesChip3Gen get chip3 => const $AssetsImagesChip3Gen();
+
+  /// Directory path: assets/images/icons
+  $AssetsImagesIconsGen get icons => const $AssetsImagesIconsGen();
+}
+
+class $AssetsImagesChip3Gen {
+  const $AssetsImagesChip3Gen();
+
+  /// File path: assets/images/chip3/chip3.jpg
+  AssetGenImage get chip3 =>
+      const AssetGenImage('assets/images/chip3/chip3.jpg');
+
+  /// List of all assets
+  List<AssetGenImage> get values => [chip3];
+}
+
+class $AssetsImagesIconsGen {
+  const $AssetsImagesIconsGen();
+
+  /// File path: assets/images/icons/dart@test.svg
+  SvgGenImage get dartTest =>
+      const SvgGenImage('assets/images/icons/dart@test.svg');
+
+  /// File path: assets/images/icons/fuchsia.svg
+  SvgGenImage get fuchsia =>
+      const SvgGenImage('assets/images/icons/fuchsia.svg');
+
+  /// List of all assets
+  List<SvgGenImage> get values => [dartTest, fuchsia];
+}
+
+class Assets {
+  const Assets._();
+
+  static const String package = 'test';
+
+  static const $AssetsImagesGen images = $AssetsImagesGen();
+}
+
+class AssetGenImage {
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.isAnimation = false,
+    this.duration = Duration.zero,
+    this.frames = 1,
+  });
+
+  final String _assetName;
+
+  static const String package = 'test';
+
+  final Size? size;
+  final Set<String> flavors;
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+
+  Image image({
+    Key? key,
+    AssetBundle? bundle,
+    ImageFrameBuilder? frameBuilder,
+    ImageErrorWidgetBuilder? errorBuilder,
+    String? semanticLabel,
+    bool excludeFromSemantics = false,
+    double? scale,
+    double? width,
+    double? height,
+    Color? color,
+    Animation<double>? opacity,
+    BlendMode? colorBlendMode,
+    BoxFit? fit,
+    AlignmentGeometry alignment = Alignment.center,
+    ImageRepeat repeat = ImageRepeat.noRepeat,
+    Rect? centerSlice,
+    bool matchTextDirection = false,
+    bool gaplessPlayback = true,
+    bool isAntiAlias = false,
+    @Deprecated('Do not specify package for a generated library asset')
+    String? package = package,
+    FilterQuality filterQuality = FilterQuality.medium,
+    int? cacheWidth,
+    int? cacheHeight,
+  }) {
+    return Image.asset(
+      _assetName,
+      key: key,
+      bundle: bundle,
+      frameBuilder: frameBuilder,
+      errorBuilder: errorBuilder,
+      semanticLabel: semanticLabel,
+      excludeFromSemantics: excludeFromSemantics,
+      scale: scale,
+      width: width,
+      height: height,
+      color: color,
+      opacity: opacity,
+      colorBlendMode: colorBlendMode,
+      fit: fit,
+      alignment: alignment,
+      repeat: repeat,
+      centerSlice: centerSlice,
+      matchTextDirection: matchTextDirection,
+      gaplessPlayback: gaplessPlayback,
+      isAntiAlias: isAntiAlias,
+      package: package,
+      filterQuality: filterQuality,
+      cacheWidth: cacheWidth,
+      cacheHeight: cacheHeight,
+    );
+  }
+
+  ImageProvider provider({
+    AssetBundle? bundle,
+    @Deprecated('Do not specify package for a generated library asset')
+    String? package = package,
+  }) {
+    return AssetImage(_assetName, bundle: bundle, package: package);
+  }
+
+  String get path => _assetName;
+
+  String get keyName => 'packages/test/$_assetName';
+}
+
+class SvgGenImage {
+  const SvgGenImage(this._assetName, {this.size, this.flavors = const {}})
+      : _isVecFormat = false;
+
+  const SvgGenImage.vec(this._assetName, {this.size, this.flavors = const {}})
+      : _isVecFormat = true;
+
+  final String _assetName;
+  final Size? size;
+  final Set<String> flavors;
+  final bool _isVecFormat;
+
+  static const String package = 'test';
+
+  _svg.SvgPicture svg({
+    Key? key,
+    bool matchTextDirection = false,
+    AssetBundle? bundle,
+    @Deprecated('Do not specify package for a generated library asset')
+    String? package = package,
+    double? width,
+    double? height,
+    BoxFit fit = BoxFit.contain,
+    AlignmentGeometry alignment = Alignment.center,
+    bool allowDrawingOutsideViewBox = false,
+    WidgetBuilder? placeholderBuilder,
+    String? semanticsLabel,
+    bool excludeFromSemantics = false,
+    _svg.SvgTheme? theme,
+    ColorFilter? colorFilter,
+    Clip clipBehavior = Clip.hardEdge,
+    @deprecated Color? color,
+    @deprecated BlendMode colorBlendMode = BlendMode.srcIn,
+    @deprecated bool cacheColorFilter = false,
+  }) {
+    final _svg.BytesLoader loader;
+    if (_isVecFormat) {
+      loader = _vg.AssetBytesLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+      );
+    } else {
+      loader = _svg.SvgAssetLoader(
+        _assetName,
+        assetBundle: bundle,
+        packageName: package,
+        theme: theme,
+      );
+    }
+    return _svg.SvgPicture(
+      loader,
+      key: key,
+      matchTextDirection: matchTextDirection,
+      width: width,
+      height: height,
+      fit: fit,
+      alignment: alignment,
+      allowDrawingOutsideViewBox: allowDrawingOutsideViewBox,
+      placeholderBuilder: placeholderBuilder,
+      semanticsLabel: semanticsLabel,
+      excludeFromSemantics: excludeFromSemantics,
+      colorFilter: colorFilter ??
+          (color == null ? null : ColorFilter.mode(color, colorBlendMode)),
+      clipBehavior: clipBehavior,
+      cacheColorFilter: cacheColorFilter,
+    );
+  }
+
+  String get path => _assetName;
+
+  String get keyName => 'packages/test/$_assetName';
+}
diff --git a/packages/core/test_resources/actual_data/assets_wrong_output_path.gen.dart b/packages/core/test_resources/actual_data/assets_wrong_output_path.gen.dart
index fba2ca3c1..866ca6657 100644
--- a/packages/core/test_resources/actual_data/assets_wrong_output_path.gen.dart
+++ b/packages/core/test_resources/actual_data/assets_wrong_output_path.gen.dart
@@ -48,12 +48,18 @@ class Assets {
 }
 
 class AssetGenImage {
-  const AssetGenImage(this._assetName, {this.size, this.flavors = const {}});
+  const AssetGenImage(
+    this._assetName, {
+    this.size,
+    this.flavors = const {},
+    this.animation,
+  });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -116,3 +122,15 @@ class AssetGenImage {
 
   String get keyName => _assetName;
 }
+
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
diff --git a/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart b/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart
index c7de4f8bc..a1cde1318 100644
--- a/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart
+++ b/packages/core/test_resources/actual_data/build_assets_build_assets.gen.dart
@@ -164,12 +164,14 @@ class AssetGenImage {
     this._assetName, {
     this.size,
     this.flavors = const {},
+    this.animation,
   });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -240,6 +242,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
diff --git a/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart b/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart
index c7de4f8bc..a1cde1318 100644
--- a/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart
+++ b/packages/core/test_resources/actual_data/build_assets_build_empty.gen.dart
@@ -164,12 +164,14 @@ class AssetGenImage {
     this._assetName, {
     this.size,
     this.flavors = const {},
+    this.animation,
   });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -240,6 +242,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
diff --git a/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart b/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart
index 2ae579906..7df752848 100644
--- a/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart
+++ b/packages/core/test_resources/actual_data/build_assets_build_runner_assets.gen.dart
@@ -157,12 +157,14 @@ class AssetGenImage {
     this._assetName, {
     this.size,
     this.flavors = const {},
+    this.animation,
   });
 
   final String _assetName;
 
   final Size? size;
   final Set<String> flavors;
+  final AssetGenImageAnimation? animation;
 
   Image image({
     Key? key,
@@ -233,6 +235,18 @@ class AssetGenImage {
   String get keyName => _assetName;
 }
 
+class AssetGenImageAnimation {
+  const AssetGenImageAnimation({
+    required this.isAnimation,
+    required this.duration,
+    required this.frames,
+  });
+
+  final bool isAnimation;
+  final Duration duration;
+  final int frames;
+}
+
 class SvgGenImage {
   const SvgGenImage(
     this._assetName, {
diff --git a/packages/core/test_resources/assets/images/animated/emoji_hugging_face.webp b/packages/core/test_resources/assets/images/animated/emoji_hugging_face.webp
new file mode 100644
index 000000000..87972d9e4
Binary files /dev/null and b/packages/core/test_resources/assets/images/animated/emoji_hugging_face.webp differ
diff --git a/packages/core/test_resources/pubspec_assets_parse_metadata.yaml b/packages/core/test_resources/pubspec_assets_parse_metadata.yaml
index c1cf89d44..d1148a96c 100644
--- a/packages/core/test_resources/pubspec_assets_parse_metadata.yaml
+++ b/packages/core/test_resources/pubspec_assets_parse_metadata.yaml
@@ -4,6 +4,9 @@ flutter_gen:
   output: lib/gen/ # Optional (default: lib/gen/)
   parse_metadata: true # Optional (default: false)
 
+  images:
+    parse_animation: true # Optional (default: false)
+
   integrations:
     flutter_svg: true
 
@@ -23,3 +26,4 @@ flutter:
     - assets/flare/
     - assets/movie/
     - assets/unknown/unknown_mime_type.bk
+    - assets/images/animated