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;
}
Related
I am using the following sample to resize the uploaded images with Blazor WebAssembly
https://www.prowaretech.com/Computer/Blazor/Examples/WebApi/UploadImages .
Still I need the original file too to be converted to base64 too and I don't know how can I access it...
I tried to find the file's original width and height to pass its to RequestImageFileAsync function but no success...
I need to store both files : the original one and the resized one.
Can you help me, please ?
Thank You Very Much !
The InputFile control emits an IBrowserFile type. RequestImageFileAsync is a convenience method on IBrowserFile to resize the image and convert the type. The result is still an IBrowserFile.
One way to do what you are asking is with SixLabors.ImageSharp. Based on the ProWareTech example, something like this...
async Task OnChange(InputFileChangeEventArgs e)
{
var files = e.GetMultipleFiles(); // get the files selected by the users
foreach(var file in files)
{
//Original-sized file
var buf1 = new byte[file.Size];
using (var stream = file.OpenReadStream())
{
await stream.ReadAsync(buf1); // copy the stream to the buffer
}
origFilesBase64.Add(new ImageFile { base64data = Convert.ToBase64String(buf1), contentType = file.ContentType, fileName = file.Name }); // convert to a base64 string!!
//Resized File
var resizedFile = await file.RequestImageFileAsync(file.ContentType, 640, 480); // resize the image file
var buf = new byte[resizedFile.Size]; // allocate a buffer to fill with the file's data
using (var stream = resizedFile.OpenReadStream())
{
await stream.ReadAsync(buf); // copy the stream to the buffer
}
filesBase64.Add(new ImageFile { base64data = Convert.ToBase64String(buf), contentType = file.ContentType, fileName = file.Name }); // convert to a base64 string!!
}
//To get the image Sizes for first image
ImageSharp.Image origImage = Image.Load<*imagetype*>(origFilesBase64[0])
int origImgHeight = origImage.Height;
int origImgWidth = origImage.Width;
ImageSharp.Image resizedImage = Image.Load<*imagetype*>(filesBase64[0])
int resizedImgHeight = resizedImage.Height;
int resizedImgWidth = resizedImage.Width;
}
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.
I read almost all the posts but still can't find a proper way if any to load a local image as ui.image so that it can be used in canvas.drawImage in Flutter. I have come out with the following code block to get an ui.image from an Asset image. However, it took a few seconds event for a 32x32 size of image and I can't figure it out when it is fully loaded and ready to be drawn in canvas.
static Future<ui.Image> askImage(String path) async {
Completer<ImageInfo> completer = Completer();
final img = Image(image: AssetImage(path));
img.image
.resolve(ImageConfiguration())
.addListener(ImageStreamListener((ImageInfo info, bool _) {
completer.complete(info);
}));
ImageInfo imageInfo = await completer.future;
return imageInfo.image;
}
static ui.Image load2(String xxxx) {
ui.Image info;
askImage(xxxx).then((info) {
if (info != null) {
print(info.width);
print(info.height);
}
return (info);
});
}
I'm also looking at the Image package 'https://pub.dev/packages/image' but I'm not sure how to convert Image from that package to ui.image which is needed for canvas.drawImage function in Flutter. I also saw an old post here (https://flutter2015.firefirestyle.net/rendering/doc-5) but I'm not sure where does the ImageResource comes from.
After reading an image with the ImageDescriptor API and resizing it by instantiating a codec I am trying to write the resized version in the application directory.
I saw that the when converting the frame into byte data I have a format which is rawUnmodified which I assumed would write the resized image in the same format as the original image. But when I tried to load the resized image I get an image format exception.
Example code:
//read the original image and obtain the image descriptor
var imageData = await file.readAsBytes();
final ImmutableBuffer buffer = await ImmutableBuffer.fromUint8List(imageData);
final imDescr = await ImageDescriptor.encoded(buffer);
//resize the image, get the first frame and convert it to bytes
Codec codec = await imDescr.instantiateCodec(targetWidth: 100, targetHeight: 100);
FrameInfo frameInfo = await codec.getNextFrame();
var bytes = await frameInfo.image.toByteData(
format: ImageByteFormat.rawUnmodified,
//note when using the png format it works, but I would like to have it in the original image format(in this case its jpg)
);
//write the resized image
Directory appDir = await getApplicationDocumentsDirectory();
var path = appDir.path;
var file = File('$path/test1.jpg');
await file.writeAsBytes(bytes.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes));
In the ImageByteFormat api it says: rawUnmodified -> Unencoded bytes, in the image's existing format. For example, a grayscale image may use a single 8-bit channel for each pixel.
But when I try to show this image the format is wrong. Anybody have an idea how to fix this?
Why use image ImageDescriptor, You can do it easily by image package
File resizeImage(File imageFile, String imageFormat, int targetWidth, int targetHeight) {
im.Image tempImage = im.decodeImage(imageFile.readAsBytesSync());
tempImage = im.bakeOrientation(tempImage);
tempImage = im.copyResize(tempImage, width: targetWidth, height: targetHeight);
File newImage;
if (imageFormat == 'jpg') {
newImage = File('newpath/test.jpg');
newImage.writeAsBytesSync(im.encodeJpg(tempImage));
return newImage;
} else if (imageFormat == 'png') {
newImage = File('newpath/test.png');
newImage.writeAsBytesSync(im.encodePng(tempImage));
return newImage;
} else {
throw ('Unknown Image Format');
}
}
I'm receiving an image on a Metro app through network socket every 1 second, loading it in an array of bytes, then convert it to a BitmapImage and display it later. All of this work fine.
The image is changing constantly on the other side. For some reason, it throws an OutOfMemory exceptions from now and then(like 1 in 10) . I fixed it by clearing the array of bytes every time the image is received. Now it works like charm.
See below for my main issue:
public static BitmapImage imag;
public static byte[] save = new byte[1];
if(recieved)
{
await reader.LoadAsync(4);
var sz = reader.ReadUInt32(); //read size
await reader.LoadAsync(sz); //read content
save = new byte[sz];
reader.ReadBytes(save);
await ImgSrcFromBytes(save)
Array.Clear(save, 0, save.Length); //issue here !!
}
public async Task<ImageSource> ImgSrcFromBytes(byte[] a)
{
imag = new BitmapImage();
var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
await stream.WriteAsync(a.AsBuffer());
stream.Seek(0);
imag.SetSource(stream);
return imag;
}
Now, i'm implementing a new function to save the image as a file if requested by the user with the code below, however, if i clear the array of bytes above, i get an unreadable image, but if i don't clear the array, i get a perfect image.
Note that no exceptions are thrown and both images have the same size.
FileSavePicker picker = new FileSavePicker();
picker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
picker.SuggestedFileName = "capture.png";
picker.FileTypeChoices.Add("Png File", new List<string>() { ".png" });
StorageFile file = await picker.PickSaveFileAsync();
if (file != null)
{
CachedFileManager.DeferUpdates(file);
await FileIO.WriteBytesAsync(file, save);
await CachedFileManager.CompleteUpdatesAsync(file);
await new Windows.UI.Popups.MessageDialog("Image Saved Successfully !").ShowAsync();
}
I hope i'm clear. It's a trade-off, if i clear the array, i will get no exceptions while receiving streams over sockets, but i won't be able to get a readable image when saving. and vice versa.