@@ -2,6 +2,7 @@ import 'dart:io';
22
33import 'package:flutter_gen_core/generators/integrations/integration.dart' ;
44import 'package:flutter_gen_core/utils/log.dart' ;
5+ import 'package:image/image.dart' as img;
56import 'package:image_size_getter/file_input.dart' ;
67import 'package:image_size_getter/image_size_getter.dart' ;
78
@@ -12,9 +13,12 @@ import 'package:image_size_getter/image_size_getter.dart';
1213class ImageIntegration extends Integration {
1314 ImageIntegration (
1415 String packageName, {
15- super .parseMetadata,
16+ required super .parseMetadata,
17+ required this .parseAnimation,
1618 }) : super (packageName);
1719
20+ final bool parseAnimation;
21+
1822 String get packageParameter => isPackage ? ' = package' : '' ;
1923
2024 String get keyName =>
@@ -33,6 +37,7 @@ class ImageIntegration extends Integration {
3337 this._assetName, {
3438 this.size,
3539 this.flavors = const {},
40+ this.animation,
3641 });
3742
3843 final String _assetName;
@@ -41,6 +46,7 @@ ${isPackage ? "\n static const String package = '$packageName';" : ''}
4146
4247 final Size? size;
4348 final Set<String> flavors;
49+ final AssetGenImageAnimation? animation;
4450
4551 Image image({
4652 Key? key,
@@ -110,19 +116,41 @@ ${isPackage ? "\n static const String package = '$packageName';" : ''}
110116
111117 String get keyName => $keyName ;
112118}
119+
120+ class AssetGenImageAnimation {
121+ const AssetGenImageAnimation({
122+ required this.isAnimation,
123+ required this.duration,
124+ required this.frames,
125+ });
126+
127+ final bool isAnimation;
128+ final Duration duration;
129+ final int frames;
130+ }
113131''' ;
114132
115133 @override
116134 String get className => 'AssetGenImage' ;
117135
118136 @override
119137 String classInstantiate (AssetType asset) {
120- final info = parseMetadata ? _getMetadata (asset) : null ;
138+ final info = parseMetadata || parseAnimation ? _getMetadata (asset) : null ;
121139 final buffer = StringBuffer (className);
122140 buffer.write ('(' );
123141 buffer.write ('\' ${asset .posixStylePath }\' ' );
124142 if (info != null ) {
125- buffer.write (', size: Size(${info .width }, ${info .height })' );
143+ buffer.write (', size: const Size(${info .width }, ${info .height })' );
144+
145+ if (info.animation case final animation? ) {
146+ buffer.write (', animation: const AssetGenImageAnimation(' );
147+ buffer.write ('isAnimation: ${animation .frames > 1 }' );
148+ buffer.write (
149+ ', duration: Duration(milliseconds: ${animation .duration .inMilliseconds })' ,
150+ );
151+ buffer.write (', frames: ${animation .frames }' );
152+ buffer.write (')' );
153+ }
126154 }
127155 if (asset.flavors.isNotEmpty) {
128156 buffer.write (', flavors: {' );
@@ -162,10 +190,53 @@ ${isPackage ? "\n static const String package = '$packageName';" : ''}
162190 FileInput (File (asset.fullPath)),
163191 );
164192 final size = result.size;
165- return ImageMetadata (size.width.toDouble (), size.height.toDouble ());
193+ final animation = parseAnimation ? _parseAnimation (asset) : null ;
194+
195+ return ImageMetadata (
196+ width: size.width.toDouble (),
197+ height: size.height.toDouble (),
198+ animation: animation,
199+ );
166200 } catch (e, s) {
167201 log.warning ('Failed to parse \' ${asset .path }\' metadata.' , e, s);
168202 }
169203 return null ;
170204 }
205+
206+ ImageAnimation ? _parseAnimation (AssetType asset) {
207+ try {
208+ final decoder = switch (asset.mime) {
209+ 'image/gif' => img.GifDecoder (),
210+ 'image/webp' => img.WebPDecoder (),
211+ _ => null ,
212+ };
213+
214+ if (decoder == null ) {
215+ return null ;
216+ }
217+
218+ final file = File (asset.fullPath);
219+ final bytes = file.readAsBytesSync ();
220+ final image = decoder.decode (bytes);
221+
222+ if (image == null ) {
223+ return null ;
224+ }
225+
226+ return ImageAnimation (
227+ frames: image.frames.length,
228+ duration: Duration (
229+ milliseconds: image.frames.fold (
230+ 0 ,
231+ (duration, frame) => duration + frame.frameDuration,
232+ ),
233+ ),
234+ );
235+ } catch (e) {
236+ stderr.writeln (
237+ '[WARNING] Failed to parse \' ${asset .path }\' animation information: $e ' ,
238+ );
239+ }
240+ return null ;
241+ }
171242}
0 commit comments