Flutter easily composite / overlay PNG images from the assets directory - image

Looking for a simple and fast example / tutorial to composite / overlay several images in Flutter, using (PNG) images from the assets directory:
Few options I've examined:
Manipulate Uint8List and use it in image.Memory
Use canvas.drawAtlas in my own Painter
use the image library (which seems a bit overkill in this case
Couldn't find any working example that suits my needs...
I'd appreciate any working example / tutorial that will help me, thanks!

4.Use combination of Stack and RepaintBoundary to generate new image:
Future<Uint8List> _takeScreenShot(context) async {
RenderRepaintBoundary boundary = _repaintKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage(pixelRatio: 2.0);
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
return pngBytes;
}
Stack(
key: _repaintKey,
children: [
//your background image,
//your png image,
],
)

Related

Convert Widget to Image.png and Save it In Created Directory Flutter

I want my app when install first thing create specific directory in internal storage and a button when clicked it's convert specific widget(screen) to image.png then save it in that created directory.
I need full code for that. I've been looking, but I haven't found an effective way.
this function is all your need for screenshot a widget and save locally:
static GlobalKey _repaintKey = GlobalKey();
Widget _yourWidget(){
return Stack(
key: _repaintKey,
children: [
],
);
}
Future<void> _takeScreenShot(context) async {
RenderRepaintBoundary boundary = _repaintKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
final path = join(
(await getTemporaryDirectory()).path, "screenshot${DateTime.now().toIso8601String()}.png");
File imgFile = File(path);
imgFile.writeAsBytes(pngBytes).then((value) {
Navigator.of(context).pushNamed(Routes.uploadImage, arguments: value.uri.path);
}).catchError((onError) {
print(onError);
});
}

Add text to an image and store - Flutter

Good day ,I am generating certificates and for this I have a template where I must write user data, for the moment I am creating the certificates in pdf format, but the ideal would be to use images or convert those pdf to image since it is easier for the user to handle images, I have not found any library capable of writing in images that works correctly.
At the moment I am trying to use Image. https://pub.dev/packages/image.
I have the following code, but it fails to add a text fragment in the image.
imagecert = await ManagerDB().getcertificate(certificatetemplate); //imagecert is uint8list
if (imagecert != null) {
mg.Image ima = mg.Image.fromBytes(300, 200, List.from(imagecert)); Image works with list<int>
mg.Image imag = mg.drawString(ima, mg.arial_14, 0, 0, 'Hello World'); //here the code does not work
List<int> data = mg.encodePng(imag);
Uint8List bytes = Uint8List.fromList(data);
setState(() {});
return bytes;
} else {
print("Enlace no encontrado");
}
I don't know if there is a simpler solution to write text in an image. It is required to store those images.
Thank you
you can put image inside widget and add to that widget text
and converted to image using globalKey (don't forget to pass globalKey to key of that sepecific widget )
Future<Uint8List> _convertWidgetToImage(GlobalKey globalKey) async {
RenderRepaintBoundary boundary =
globalKey.currentContext!.findRenderObject() as RenderRepaintBoundary;
ui.Image image = await boundary.toImage();
ByteData byteData =
(await (image.toByteData(format: ui.ImageByteFormat.png)))!;
Uint8List pngBytes = byteData.buffer.asUint8List();
return pngBytes;
}

High resolution Image from Flutter Widget

In my App, I need to create Images from the Widgets shown on Screen.
I used the below code to create the Image using RepaintBoundary.
But the image I get is of 72 PPI.
Is there any way I can get An Image of Higher Resolution?
Future<void> takePicture() async {
RenderRepaintBoundary boundary = genKey.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
final directory = (await getApplicationDocumentsDirectory()).path;
ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
Uint8List pngBytes = byteData.buffer.asUint8List();
File imgFile = new File('$directory/photo.png');
imgFile.writeAsBytes(pngBytes);
}
use this line will improve the "boundary.toImage(pixelRatio: 10.0)"
pixelRatio use as double to improve the quality as u want.

How to resize a network image before showing it as NetworkImage in flutter web?

My goal is to increase the performance of my website by downscaling images.
When i show NetworkImages they always render the full source image resolution (e.g. 7000x4667 pixel). The widget itself mostly has a smaller size (e.g. 200x200 pixel). I have the image url and want to scale the 7000x4667 pixel image down to 200x200 before loading it in the NetworkImage widget.
What i already tried is the answer from this question:
Flutter - Resize network image
That does work in flutter for mobil but not in flutter web as the line ByteData originalByteData = await originalUiImage.toByteData(); returns null in flutter web.
Already thank you a lot in advance for your help.
I found a solution that propably suits you . Speed is fantastic and size of the image is reduced significantly.
late Uint8List targetlUinit8List;
late Uint8List originalUnit8List;
Future<Uint8List> _resizeImage() async {
var imageUrl = Uri.parse('https://picsum.photos/250?image=9');
http.Response response = await http.get(imageUrl);
originalUnit8List = response.bodyBytes;
ui.Image originalUiImage = await decodeImageFromList(originalUnit8List);
ByteData? originalByteData = await originalUiImage.toByteData();
print('original image ByteData size is ${originalByteData!.lengthInBytes}');
var codec = await ui.instantiateImageCodec(originalUnit8List,
targetHeight: 200, targetWidth: 200);
var frameInfo = await codec.getNextFrame();
ui.Image targetUiImage = frameInfo.image;
ByteData? targetByteData =
await targetUiImage.toByteData(format: ui.ImageByteFormat.png);
print('target image ByteData size is ${targetByteData!.lengthInBytes}');
targetlUinit8List = targetByteData.buffer.asUint8List();
//remove delay function
await Future.delayed(Duration(seconds: 2));
return targetlUinit8List;
}
Then I have a futureBuilder for my example , but you can use anything you want :
if (snapshot.hasData) {
children = <Widget>[
const Icon(
Icons.check_circle_outline,
color: Colors.green,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Image.memory(snapshot.data!),
)
];
}
Only thing left to implement is to dispose the unused variables , and I have no idea how to do it (I am not the best at flutter). I want to know if anyone implements this with disposed variables

Change Image Size From Uint8List Data in Flutter

I'm trying to change image size from uint8list data.
There are lots of Image classes in Flutter as you know,
and The final type of image I want to get is ui.Image.
I get Uint8List Image(.jpg) data from socket communication.
Now, I want to set the size of the image and get the Image of ui.Image at the end.
I tried to do that through (dart:ui : ui, package:image/image.dart : IMG)
IMG.Image img = IMG.decodeImage(data);
IMG.Image resized = IMG.copyResize(img, width: 400, height: 200);
ui.Codec codec = await ui.instantiateImageCodec(IMG.encodeJpg(resized));
ui.Image image = (await codec.getNextFrame()).image;
,but It freezes the app.
How can I do that? Is there any way? Thank you.
Additionally,
In "flutter/lib/src/widgets/image.dart",
Image.memory(Uint8List, width, height) can make it be easy to set image size.
Is there any way to get Uint8List from that Image widget?
I resized the image data in Uint8List like below.
import package:image/image.dart as IMG
Uint8List resizeImage(Uint8List data) {
Uint8List resizedData = data;
IMG.Image img = IMG.decodeImage(data);
IMG.Image resized = IMG.copyResize(img, width: img.width*2, height: img.height*2);
resizedData = IMG.encodeJpg(resized);
return resizedData;
}
IMG : flutter image package
Have you tried using ui.decodeImageFromList instead of ui.instantiateImageCodec and getNextFrame() ?
import 'dart:ui' as ui;
ui.decodeImageFromList(IMG.encodeJpg(resized), (ui.Image img) {
// returned ui.Image
});

Resources