I can set a standard flutter image from memory or from a file, but not an ImageProvider as required by the PhotoView framework.
The PhotoView framework accepts an AssetImage as a type of provider but not any of the other ImageProvider types (File and Memory).
What might be a workaround? I'd think the framework would support image sources other than from a project's assets
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:photo_view/photo_view.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
import 'dart:ui' as ui;
import 'dart:typed_data';
import 'dart:async';
import 'dart:io';
class TestImageDraw extends StatefulWidget {
TestImageDraw({Key key, this.title}) : super(key: key);
final String title;
@override
_TestImageDrawState createState() => _TestImageDrawState();
}
class _TestImageDrawState extends State<TestImageDraw> {
ImageProvider _imageProvider;
@override
void initState() {
super.initState();
_imageProvider = NetworkImage(
"https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png");
}
_generateImage() {
GenImage.generateImage().then((generatedImage) async {
ByteData image =
await generatedImage.toByteData(format: ui.ImageByteFormat.png);
// String base64 = base64Encode(image.buffer.asInt64List());
// print(base64);
// Uint8List bytes = base64Decode(base64);
// _imageProvider = MemoryImage(bytes);
_imageProvider = MemoryImage(image.buffer.asUint8List());
setState(() {});
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text(widget.title),
),
body: Container(
child: Column(children: <Widget>[
//Image will display
Image(image: _imageProvider),
Container(
child: _imageProvider != null
? PhotoView(imageProvider: _imageProvider)
: Container()),
])),
floatingActionButton: new FloatingActionButton(
onPressed: _generateImage,
tooltip: 'Generate',
child: new Icon(Icons.add),
),
);
}
}
class GenImage {
static Future<ui.Image> generateImage() async {
ui.PictureRecorder recorder = new ui.PictureRecorder();
Canvas c = new Canvas(recorder);
var rect = new Rect.fromLTWH(0.0, 0.0, 200.0, 200.0);
c.clipRect(rect);
final paint = new Paint();
paint.strokeWidth = 1;
paint.color = const Color(0xFF0000FF);
paint.style = PaintingStyle.stroke;
final offset = new Offset(100.0, 100.0);
c.drawCircle(offset, 50.0, paint);
var picture = recorder.endRecording();
final image = await picture.toImage(500, 500);
return image;
}
}
PhotoView author here, the widget works fine with all ImageProvider (Memory and File extend ImageProvider).
The problem is how you are creating the provider. image.buffer.asUint8List()
prints a headless map of bits, making it impossible to display.
The head of a bitmap contains information such size of each pixel (in bits) and the size of the image (in pixels).
I've actually created a whole package around that.
With bitmap package, you can retrieve a headful file from an ui.Image
instance:
First, create a bitmap instance:
ByteData bytedata = await image.toByteData();
Bitmap bitmap = Bitmap.fromHeadless(imageWidth, imageHeight, bytedata.buffer.asUint8List());
Then, recover the final map of bits:
Uint8List headedIntList = bitmap.buildHeaded();
Now you can pass it into PhotoView:
PhotoView(imageProvider: headedIntList)