Commit 6c93270d authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

FileImage (#6853)

parent d3dc5d7c
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:io' show File;
import 'dart:ui' show Size, Locale, hashValues;
import 'dart:ui' as ui show Image;
import 'dart:typed_data';
......@@ -370,6 +371,68 @@ class NetworkImage extends ImageProvider<NetworkImage> {
String toString() => '$runtimeType("$url", scale: $scale)';
}
/// Decodes the given [File] object as an image, associating it with the given
/// scale.
class FileImage extends ImageProvider<FileImage> {
/// Creates an object that decodes a [File] as an image.
///
/// The arguments must not be null.
const FileImage(this.file, { this.scale: 1.0 });
/// The file to decode into an image.
final File file;
/// The scale to place in the [ImageInfo] object of the image.
final double scale;
@override
Future<FileImage> obtainKey(ImageConfiguration configuration) {
return new SynchronousFuture<FileImage>(this);
}
@override
ImageStreamCompleter load(FileImage key) {
return new OneFrameImageStreamCompleter(
_loadAsync(key),
informationCollector: (StringBuffer information) {
information.writeln('Path: ${file?.path}');
}
);
}
Future<ImageInfo> _loadAsync(FileImage key) async {
assert(key == this);
Uint8List bytes = await file.readAsBytes();
if (bytes.lengthInBytes == 0)
return null;
final ui.Image image = await decodeImageFromList(bytes);
if (image == null)
return null;
return new ImageInfo(
image: image,
scale: key.scale,
);
}
@override
bool operator ==(dynamic other) {
if (other.runtimeType != runtimeType)
return false;
final FileImage typedOther = other;
return file?.path == file?.path
&& scale == typedOther.scale;
}
@override
int get hashCode => hashValues(file?.path, scale);
@override
String toString() => '$runtimeType("${file?.path}", scale: $scale)';
}
/// Fetches an image from an [AssetBundle], associating it with the given scale.
///
/// This implementation requires an explicit final [name] and [scale] on
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io' show Platform;
import 'dart:io' show File, Platform;
import 'package:flutter/services.dart';
import 'package:meta/meta.dart';
......@@ -14,7 +14,8 @@ import 'media_query.dart';
export 'package:flutter/services.dart' show
AssetImage,
ExactAssetImage,
NetworkImage;
NetworkImage,
FileImage;
/// Creates an [ImageConfiguration] based on the given [BuildContext] (and
/// optionally size).
......@@ -37,9 +38,10 @@ ImageConfiguration createLocalImageConfiguration(BuildContext context, { Size si
/// specified:
///
/// * [new Image], for obtaining an image from an [ImageProvider].
/// * [new Image.network], for obtaining an image from a URL.
/// * [new Image.asset], for obtaining an image from an [AssetBundle]
/// using a key.
/// * [new Image.network], for obtaining an image from a URL.
/// * [new Image.file], for obtaining an image from a [File].
///
/// To automatically perform pixel-density-aware asset resolution, specify the
/// image using an [AssetImage] and make sure that a [MaterialApp], [WidgetsApp],
......@@ -90,6 +92,26 @@ class Image extends StatefulWidget {
}) : image = new NetworkImage(src, scale: scale),
super(key: key);
/// Creates a widget that displays an [ImageStream] obtained from a [File].
///
/// The [file], [scale], and [repeat] arguments must not be null.
///
/// On Android, this may require the
/// `android.permission.READ_EXTERNAL_STORAGE` permission.
Image.file(File file, {
Key key,
double scale: 1.0,
this.width,
this.height,
this.color,
this.fit,
this.alignment,
this.repeat: ImageRepeat.noRepeat,
this.centerSlice,
this.gaplessPlayback: false
}) : image = new FileImage(file, scale: scale),
super(key: key);
/// Creates a widget that displays an [ImageStream] obtained from an asset
/// bundle. The key for the image is given by the `name` argument.
///
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment