@@ -8,38 +8,72 @@ import 'package:flutter/painting.dart';
88import 'package:flutter/foundation.dart'
99 show SynchronousFuture, describeIdentity;
1010
11+ class _FutureImageStreamCompleter extends ImageStreamCompleter {
12+ final Future <double > futureScale;
13+ final InformationCollector informationCollector;
14+
15+ _FutureImageStreamCompleter (
16+ {Future <ui.Codec > codec, this .futureScale, this .informationCollector})
17+ : assert (codec != null ),
18+ assert (futureScale != null ) {
19+ codec.then <void >(_onCodecReady, onError: (dynamic error, StackTrace stack) {
20+ reportError (
21+ context: ErrorDescription ('resolving a single-frame image stream' ),
22+ exception: error,
23+ stack: stack,
24+ informationCollector: informationCollector,
25+ silent: true ,
26+ );
27+ });
28+ }
29+
30+ Future <void > _onCodecReady (ui.Codec codec) async {
31+ try {
32+ ui.FrameInfo nextFrame = await codec.getNextFrame ();
33+ double scale = await futureScale;
34+ setImage (ImageInfo (image: nextFrame.image, scale: scale));
35+ } catch (exception, stack) {
36+ reportError (
37+ context: ErrorDescription ('resolving an image frame' ),
38+ exception: exception,
39+ stack: stack,
40+ informationCollector: this .informationCollector,
41+ silent: true ,
42+ );
43+ }
44+ }
45+ }
46+
1147/// Performs exactly like a [MemoryImage] but instead of taking in bytes it takes
1248/// in a future that represents bytes.
13- class FutureMemoryImage extends ImageProvider <FutureMemoryImage > {
49+ class _FutureMemoryImage extends ImageProvider <_FutureMemoryImage > {
1450 /// Constructor for FutureMemoryImage. [_futureBytes] is the bytes that will
15- /// be loaded into an image and [scale ] is the scale that will be applied to
51+ /// be loaded into an image and [_futureScale ] is the scale that will be applied to
1652 /// that image to account for high-resolution images.
17- const FutureMemoryImage (this ._futureBytes, { this .scale = 1.0 } )
53+ const _FutureMemoryImage (this ._futureBytes, this ._futureScale )
1854 : assert (_futureBytes != null ),
19- assert (scale != null );
55+ assert (_futureScale != null );
2056
2157 final Future <Uint8List > _futureBytes;
22-
23- /// The scale to place in the ImageInfo object of the image.
24- final double scale;
58+ final Future <double > _futureScale;
2559
2660 /// See [ImageProvider.obtainKey] .
2761 @override
28- Future <FutureMemoryImage > obtainKey (ImageConfiguration configuration) {
29- return SynchronousFuture <FutureMemoryImage >(this );
62+ Future <_FutureMemoryImage > obtainKey (ImageConfiguration configuration) {
63+ return SynchronousFuture <_FutureMemoryImage >(this );
3064 }
3165
3266 /// See [ImageProvider.load] .
3367 @override
34- ImageStreamCompleter load (FutureMemoryImage key, DecoderCallback decode) {
35- return MultiFrameImageStreamCompleter (
68+ ImageStreamCompleter load (_FutureMemoryImage key, DecoderCallback decode) {
69+ return _FutureImageStreamCompleter (
3670 codec: _loadAsync (key, decode),
37- scale : key.scale ,
71+ futureScale : _futureScale ,
3872 );
3973 }
4074
4175 Future <ui.Codec > _loadAsync (
42- FutureMemoryImage key, DecoderCallback decode) async {
76+ _FutureMemoryImage key, DecoderCallback decode) async {
4377 assert (key == this );
4478 return _futureBytes.then ((Uint8List bytes) {
4579 return decode (bytes);
@@ -50,18 +84,19 @@ class FutureMemoryImage extends ImageProvider<FutureMemoryImage> {
5084 @override
5185 bool operator == (dynamic other) {
5286 if (other.runtimeType != runtimeType) return false ;
53- final FutureMemoryImage typedOther = other;
54- return _futureBytes == typedOther._futureBytes && scale == typedOther.scale;
87+ final _FutureMemoryImage typedOther = other;
88+ return _futureBytes == typedOther._futureBytes &&
89+ _futureScale == typedOther._futureScale;
5590 }
5691
5792 /// See [ImageProvider.hashCode] .
5893 @override
59- int get hashCode => hashValues (_futureBytes.hashCode, scale );
94+ int get hashCode => hashValues (_futureBytes.hashCode, _futureScale );
6095
6196 /// See [ImageProvider.toString] .
6297 @override
6398 String toString () =>
64- '$runtimeType (${describeIdentity (_futureBytes )}, scale: $scale )' ;
99+ '$runtimeType (${describeIdentity (_futureBytes )}, scale: $_futureScale )' ;
65100}
66101
67102/// Class to help loading of iOS platform images into Flutter.
@@ -77,8 +112,15 @@ class IosPlatformImages {
77112 /// Throws an exception if the image can't be found.
78113 ///
79114 /// See [https://developer.apple.com/documentation/uikit/uiimage/1624146-imagenamed?language=objc]
80- static FutureMemoryImage load (String name) {
81- return FutureMemoryImage (_channel.invokeMethod ('loadImage' , name));
115+ static ImageProvider load (String name) {
116+ Future <Map > loadInfo = _channel.invokeMethod ('loadImage' , name);
117+ Completer <Uint8List > bytesCompleter = Completer <Uint8List >();
118+ Completer <double > scaleCompleter = Completer <double >();
119+ loadInfo.then ((map) {
120+ scaleCompleter.complete (map["scale" ]);
121+ bytesCompleter.complete (map["data" ]);
122+ });
123+ return _FutureMemoryImage (bytesCompleter.future, scaleCompleter.future);
82124 }
83125
84126 /// Resolves an URL for a resource. The equivalent would be:
0 commit comments