How to use an ui.Image as an ImageProvider data source
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)
Yarm
Updated on December 15, 2022Comments
-
Yarm over 1 year
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; } }