Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/ios_platform_images/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
## 0.1.0

* Fixed a bug where the scale value of the image wasn't respected.

## 0.0.1

Initial release. Includes functionality to share images iOS images with Flutter
* Initial release. Includes functionality to share images iOS images with Flutter
and Flutter assets with iOS.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
UIImage* image = [UIImage imageNamed:name];
NSData* data = UIImagePNGRepresentation(image);
if (data) {
result([FlutterStandardTypedData typedDataWithBytes:data]);
result(@{
@"scale" : @(image.scale),
@"data" : [FlutterStandardTypedData typedDataWithBytes:data],
});
} else {
result(nil);
}
Expand Down
80 changes: 61 additions & 19 deletions packages/ios_platform_images/lib/ios_platform_images.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,38 +8,72 @@ import 'package:flutter/painting.dart';
import 'package:flutter/foundation.dart'
show SynchronousFuture, describeIdentity;

class _FutureImageStreamCompleter extends ImageStreamCompleter {
final Future<double> futureScale;
final InformationCollector informationCollector;

_FutureImageStreamCompleter(
{Future<ui.Codec> codec, this.futureScale, this.informationCollector})
: assert(codec != null),
assert(futureScale != null) {
codec.then<void>(_onCodecReady, onError: (dynamic error, StackTrace stack) {
reportError(
context: ErrorDescription('resolving a single-frame image stream'),
exception: error,
stack: stack,
informationCollector: informationCollector,
silent: true,
);
});
}

Future<void> _onCodecReady(ui.Codec codec) async {
try {
ui.FrameInfo nextFrame = await codec.getNextFrame();
double scale = await futureScale;
setImage(ImageInfo(image: nextFrame.image, scale: scale));
} catch (exception, stack) {
reportError(
context: ErrorDescription('resolving an image frame'),
exception: exception,
stack: stack,
informationCollector: this.informationCollector,
silent: true,
);
}
}
}

/// Performs exactly like a [MemoryImage] but instead of taking in bytes it takes
/// in a future that represents bytes.
class FutureMemoryImage extends ImageProvider<FutureMemoryImage> {
class _FutureMemoryImage extends ImageProvider<_FutureMemoryImage> {
/// Constructor for FutureMemoryImage. [_futureBytes] is the bytes that will
Copy link
Contributor

@collinjackson collinjackson Dec 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this class is private you probably don't need dartdoc comments here.

If you do feel compelled to document _futureBytes and _futureScale you should do that where they're defined. (First Dartdoc paragraph should always be a single sentence.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I already went through the trouble documenting it. I know they aren't required now, but they are still useful.

/// be loaded into an image and [scale] is the scale that will be applied to
/// be loaded into an image and [_futureScale] is the scale that will be applied to
/// that image to account for high-resolution images.
const FutureMemoryImage(this._futureBytes, {this.scale = 1.0})
const _FutureMemoryImage(this._futureBytes, this._futureScale)
: assert(_futureBytes != null),
assert(scale != null);
assert(_futureScale != null);

final Future<Uint8List> _futureBytes;

/// The scale to place in the ImageInfo object of the image.
final double scale;
final Future<double> _futureScale;

/// See [ImageProvider.obtainKey].
@override
Future<FutureMemoryImage> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<FutureMemoryImage>(this);
Future<_FutureMemoryImage> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<_FutureMemoryImage>(this);
}

/// See [ImageProvider.load].
@override
ImageStreamCompleter load(FutureMemoryImage key, DecoderCallback decode) {
return MultiFrameImageStreamCompleter(
ImageStreamCompleter load(_FutureMemoryImage key, DecoderCallback decode) {
return _FutureImageStreamCompleter(
codec: _loadAsync(key, decode),
scale: key.scale,
futureScale: _futureScale,
);
}

Future<ui.Codec> _loadAsync(
FutureMemoryImage key, DecoderCallback decode) async {
_FutureMemoryImage key, DecoderCallback decode) async {
assert(key == this);
return _futureBytes.then((Uint8List bytes) {
return decode(bytes);
Expand All @@ -50,18 +84,19 @@ class FutureMemoryImage extends ImageProvider<FutureMemoryImage> {
@override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType) return false;
final FutureMemoryImage typedOther = other;
return _futureBytes == typedOther._futureBytes && scale == typedOther.scale;
final _FutureMemoryImage typedOther = other;
return _futureBytes == typedOther._futureBytes &&
_futureScale == typedOther._futureScale;
}

/// See [ImageProvider.hashCode].
@override
int get hashCode => hashValues(_futureBytes.hashCode, scale);
int get hashCode => hashValues(_futureBytes.hashCode, _futureScale);

/// See [ImageProvider.toString].
@override
String toString() =>
'$runtimeType(${describeIdentity(_futureBytes)}, scale: $scale)';
'$runtimeType(${describeIdentity(_futureBytes)}, scale: $_futureScale)';
}

/// Class to help loading of iOS platform images into Flutter.
Expand All @@ -77,8 +112,15 @@ class IosPlatformImages {
/// Throws an exception if the image can't be found.
///
/// See [https://developer.apple.com/documentation/uikit/uiimage/1624146-imagenamed?language=objc]
static FutureMemoryImage load(String name) {
return FutureMemoryImage(_channel.invokeMethod('loadImage', name));
static ImageProvider load(String name) {
Future<Map> loadInfo = _channel.invokeMethod('loadImage', name);
Completer<Uint8List> bytesCompleter = Completer<Uint8List>();
Completer<double> scaleCompleter = Completer<double>();
loadInfo.then((map) {
scaleCompleter.complete(map["scale"]);
bytesCompleter.complete(map["data"]);
});
return _FutureMemoryImage(bytesCompleter.future, scaleCompleter.future);
}

/// Resolves an URL for a resource. The equivalent would be:
Expand Down
2 changes: 1 addition & 1 deletion packages/ios_platform_images/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: ios_platform_images
description: A plugin to share images between Flutter and iOS in add-to-app setups.
version: 0.0.1
version: 0.1.0
homepage: https://github.com/flutter/plugins/tree/master/packages/ios_platform_images/ios_platform_images

environment:
Expand Down