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

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);
});
}

Related

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 load network image in Flame?

In Flame documentation, Image class just load from asset folder.
bgSprite = Sprite('avatar/avatar-sample.png');
How can I load network images in Flame.
You could do something like this in versions after 1.0.0:
import dart:ui; // This is the package you want the Image class from, there are several
Future<Image> getImage(String path) async {
Completer<ImageInfo> completer = Completer();
var img = new NetworkImage(path);
img.resolve(ImageConfiguration()).addListener(ImageStreamListener((ImageInfo info,bool _){
completer.complete(info);
}));
ImageInfo imageInfo = await completer.future;
return imageInfo.image;
}
and then in your onLoad method, just initiate bgSprite:
#override
Future<void> onLoad() async {
final image = await getImage("your-url.com/sample.png");
bgSprite = Sprite(image);
}
In 0.28.0, which it looks like you are running, you'll just replace the last line with (but I really recommend upgrading to a version after 1.0.0):
bgSprite = Sprite.fromImage(image);

How to convert image to uint8list in flutter without using async?

PdfImage requires Uint8List as param but I have ImageProvider. So how can we convert image to uint8list in flutter?
var imageProvider = AssetImage('assets/test.jpg');
final image = PdfImage(
pdf.document,
image:???, /// Uint8List required
width: img.width,
height: img.height,
);
Using FutureBuilder:
Use rootBundle.load()
(await rootBundle.load(/*YOUR IMAGE PATH HERE*/)).buffer.asUint8List()
UPDATE
As load() is an async operation, you need to wait until the data is fully loaded. Try substituting the UI with some loading indicator until then.
ByteData imageData;
#override
void initState() {
rootBundle.load('assets/test.jpg')
.then((data) => setState(() => this.imageData = data));
}
#override
Widget build(BuildContext context) {
if (imageData == null) {
return Center(child: CircularProgressIndicator());
}
final image = PdfImage(
pdf.document,
image: imageData.buffer.asUint8List(),
width: img.width,
height: img.height,
);
...
}
I tried different solutions to convert image to UInt8List and finally found one Solution. It worked for me.
XFile? image = await imagePicker.pickImage(
source: ImageSource.gallery,
); // Upload file from gallery
final bytes = await image!.readAsBytes(); // Converts the file to UInt8List
for the output, i used MemoryImage
MemoryImage(bytes!);
in Flutter, attaching local image to pdf file.
Actually It's a simple solution to add our local image to pdf file.
just copy paste the following code and try
final ByteData bytes = await rootBundle.load('assets/logo.jpg');
final Uint8List list = bytes.buffer.asUint8List();
final image = PdfImage.file(
pdf.document,
bytes: list,
);
pdf.addPage(pw.Page(build: (pw.Context context) {
return pw.Center(
child: pw.Image(image),
); // Center
}));
You could split initState into two if you prefer:
#override
void initState() {
loadAsset('test.jpg');
}
void loadAsset(string name) async {
var data = await rootBundle.load('assets/$name');
setState(() => this.imageData = data);
}
Note that this will cause build() to run an extra time but I find it easier on the eye. With Michael's circular Indicator, this is a harmless extra cycle.

How to get a Flutter Uint8List from a Network Image?

I'm trying to convert a network image into a file and the first part of that is to convert it into a Uint8List. Here is how I'm doing this with 1 of my asset images...
final ByteData bytes = await rootBundle.load('assests/logo');
final Uint8List list = bytes.buffer.asUint8List();
final tempDir = await getTemporaryDirectory();
final file = await new File('${tempDir.path}/image.jpg').create();
file.writeAsBytesSync(list);
How can I do this with Image.network(imageUrl.com/image)
The simplest way seeems to get the http response using the image url and response.bodyBytes would contain the data in Uint8List.
http.Response response = await http.get(
'https://flutter.io/images/flutter-mark-square-100.png',
);
response.bodyBytes //Uint8List
Now you can do things like converting to base64 encoded string base64.encode(response.bodyBytes);
Update: With newer version of http, you need to add Uri.parse()
Eg.
http.Response response = await http.get(
Uri.parse('https://flutter.io/images/flutter-mark-square-100.png'),
);
I figured out a different solution. Hope it helps someone.
import 'dart:typed_data';
import 'package:flutter/services.dart';
Uint8List bytes = (await NetworkAssetBundle(Uri.parse(imageUrl))
.load(imageUrl))
.buffer
.asUint8List();
void initState() {
super.initState();
var sunImage = new NetworkImage(
"https://resources.ninghao.org/images/childhood-in-a-picture.jpg");
sunImage.obtainKey(new ImageConfiguration()).then((val) {
var load = sunImage.load(val);
load.addListener((listener, err) async {
setState(() => image = listener);
});
});
}
See also https://github.com/flutter/flutter/issues/23761#issuecomment-434606683
Then you can use image.toByteData().buffer.asUInt8List()
See also https://docs.flutter.io/flutter/dart-ui/Image/toByteData.html
The answers here are relevant and help explain how dart and flutter image compression/conversion works. If you would like a shortcut, there is this package https://pub.dev/packages/network_image_to_byte that makes it really easy.
After trying for hours this is what helped me
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
Future<File> getFileFromNetworkImage(String imageUrl) async {
var response = await http.get(imageUrl);
final documentDirectory = await getApplicationDocumentsDirectory();
String fileName = DateTime.now().millisecondsSinceEpoch.toString();
File file = File(path.join(documentDirectory.path, '$fileName.png'));
file.writeAsBytes(response.bodyBytes);
return file;
}
final file = await getFileFromNetworkImage("<your network image Url here>");
Note: this also converts mp4 videos to a File.
originally answered here
As http needs Uri this would be helpful:
you should remove the begining serverAddress from your ImageAddress first :
something like this in my case that I have 3001 in my url:
String serverAddress = 'myAddress.com:3001';
int indexOf3001 = imageAddress.indexOf('3001');
String trimmedImageAddress= imageAddress.substring(indexOf3001 + 4);
then :
var imageUrl = Uri.https(serverAddress, trimmedImageAddress);
final http.Response responseData = await http.get(imageUrl);
Uint8List imageBytes = responseData.bodyBytes;
this works on device and web too, hope it can help.

Resources