Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 8b2d5da

Browse files
authored
[ios_platform_images] Made ios_platform_images set the correct image scale. (#2414)
1 parent 399be06 commit 8b2d5da

File tree

4 files changed

+71
-22
lines changed

4 files changed

+71
-22
lines changed
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1+
## 0.1.0
2+
3+
* Fixed a bug where the scale value of the image wasn't respected.
4+
15
## 0.0.1
26

3-
Initial release. Includes functionality to share images iOS images with Flutter
7+
* Initial release. Includes functionality to share images iOS images with Flutter
48
and Flutter assets with iOS.

packages/ios_platform_images/ios/Classes/IosPlatformImagesPlugin.m

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
2020
UIImage* image = [UIImage imageNamed:name];
2121
NSData* data = UIImagePNGRepresentation(image);
2222
if (data) {
23-
result([FlutterStandardTypedData typedDataWithBytes:data]);
23+
result(@{
24+
@"scale" : @(image.scale),
25+
@"data" : [FlutterStandardTypedData typedDataWithBytes:data],
26+
});
2427
} else {
2528
result(nil);
2629
}

packages/ios_platform_images/lib/ios_platform_images.dart

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,72 @@ import 'package:flutter/painting.dart';
88
import '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:

packages/ios_platform_images/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: ios_platform_images
22
description: A plugin to share images between Flutter and iOS in add-to-app setups.
3-
version: 0.0.1
3+
version: 0.1.0
44
homepage: https://github.com/flutter/plugins/tree/master/packages/ios_platform_images/ios_platform_images
55

66
environment:

0 commit comments

Comments
 (0)