reviving image through sockets [Windows Store Apps - C# ] - image

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.

Related

Resize and Upload Images with Blazor WebAssembly

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

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

UWP FileOpenPicker locks\freezes app in debug

If the debugger is attached, calling this function causes the app to hang. If I run without a debugger, there is no hang, and file pickers work perfectly.
private async void OnClick(object sender, RoutedEventArgs e)
{
FileOpenPicker openPicker = new FileOpenPicker();
}
I'm certain this is something super simple, but I just don't know.
Edit:
Here's how I'm using it. Keep in mind, that the simpler function creates the hang issue without all my extra code after it. I've stuffed up the image saving, but that's a separate issue I want to debug when I solve what this post is about.
.
public async Task ImportHeader()
{
FileOpenPicker openPicker = new FileOpenPicker();
openPicker.ViewMode = PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".png");
// For multiple image selection
var files = await openPicker.PickMultipleFilesAsync();
foreach (StorageFile singleImage in files)
{
IRandomAccessStream stream = await singleImage.OpenAsync(Windows.Storage.FileAccessMode.Read);
var image = new BitmapImage();
image.SetSource(stream);
HeaderImage.Source = image;
//We also save this to disk for later
Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile file = await storageFolder.CreateFileAsync("header.jpg", Windows.Storage.CreationCollisionOption.ReplaceExisting);
stream.Seek(0);
using (StreamWriter bw = new StreamWriter(file.OpenStreamForWriteAsync().Result))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, stream);
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(HeaderImage, (int)HeaderImage.Width, (int)HeaderImage.Height);
var pixels = await renderTargetBitmap.GetPixelsAsync();
byte[] bytes = pixels.ToArray();
bw.Write(stream);
}
}
}
This has happened to me as well on some of the recent Windows 10 Insider Preview builds, while the process works flawlessly on stable builds of Windows 10. I think you can assume the cause is there instead of your code.

Unable to rotate image in windows store app

I'm attempting to take a photo with my device camera, but images taken with the device held in "portrait" mode come out sideways. I'd like to rotate them before saving them, but the solution that I keep coming across isn't working for me.
Windows.Storage.Streams.InMemoryRandomAccessStream stream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
imagePreview.Source = null;
await stream.WriteAsync(currentImage.AsBuffer());
stream.Seek(0);
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(stream, decoder);
encoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees;
encoder.IsThumbnailGenerated = false;
await encoder.FlushAsync();
//save the image
StorageFolder folder = KnownFolders.SavedPictures;
StorageFile capturefile = await folder.CreateFileAsync("photo_" + DateTime.Now.Ticks.ToString() + ".bmp", CreationCollisionOption.ReplaceExisting);
string captureFileName = capturefile.Name;
//store stream in file
using (var fileStream = await capturefile.OpenStreamForWriteAsync())
{
try
{
//because of using statement stream will be closed automatically after copying finished
await Windows.Storage.Streams.RandomAccessStream.CopyAsync(stream, fileStream.AsOutputStream());
}
catch
{
}
}
this produces the original image with no rotation applied to it. I've looked at a lot of samples, and can't figure out what I'm doing wrong.

Images takes so much time to load in j2me mobile application

I have used below code to fetch image from server. I have 60 different images placed on server. I have urls of all those images. By using while loop I am getting all these images but it's taking so much time to load image from server.
What can I do to get these images as fast as possible?
public Image getImagefromURL(String imageURL) {
DataInputStream is = null;
StringBuffer sb = new StringBuffer();
Image img = null;
try {
HttpConnection c = (HttpConnection) Connector.open(imageURL);
int len = (int) c.getLength();
if (len > 0) {
is = c.openDataInputStream();
byte[] data = new byte[len];
is.readFully(data);
img = Image.createImage(data, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
}
return img;
}
And also one thing is happening that when I fetch first image, application is confirming me like "Application wants to connect to [URL of image location] using airtime. IS it ok to use airtime?" here I want to hide my path of image location. How can I do that?
The bigger the image, the longer it will take to load it. Make sure your PNG images are compressed with a tool, for example, PNGGauntlet.
You can also add a local cache on the application side using RMS.
And a last tip... You should not rely on HttpConnection.getLength, it might come as zero even when there is data to be read.

Resources