I am trying to load an image from a memory stream:
Stream imageStream = new MemoryStream(bitmapData); //bitmap data is byte array
MainThread.BeginInvokeOnMainThread(() =>
{
Drawing.Source = ImageSource.FromStream(() => imageStream);
});
(This work fine with the sfsignature control)
also, when I add this after trying to load the image:
Drawing.AddShape(AnnotationShape.Pen, new ImageEditorShapeSettings() { Color = Colors.Black, StrokeThickness = 2 });
It does not work, it does work if I do not try to load the image from the memory stream.
I am not getting any exceptions or errors.
Hi Phunction,
Based on the shared information we have checked your query. If you set the Stream source with a local variable, the stream will be closed after the image uses it, and you cannot process the stream again. So, we recommend using stream images by creating a new stream instance inside the Lamba function so that you can process them whenever needed.
C#:
|
MainThread.BeginInvokeOnMainThread(() =>
{
Drawing.Source = ImageSource.FromStream(() => new MemoryStream(bitmapData));
});
|
Please refer to the following UG link to know about loading an image from stream: [UG documentation]
Regards,
Vidyalakshmi M.
Thanks, that fixes that part, but I have anotherquestion.
I would like to save the image In the OnDissappearing method, is that possible?
Is there an event similar to PenUp or DrawingEnd I can use?
Hi Phunction,
Regarding query “Save the image In the OnDissappearing method, is that possible?”
You can save the image in the OnDisappearing method as shown in the code snippet below:
|
protected override void OnDisappearing() { base.OnDisappearing();
this.imageEditor.Save(ImageFileType.Png, "D:\\Syncfusion\\Pictures", "Syncfusion"); }
|
Regarding query ”Event similar to PenUp or DrawingEnd”
You can use the ToolBarItemSelected event for this purpose. When you complete the drawing and click the tick icon in the HeaderToolbar to save the changes, this event will be triggered. You can handle this event and perform any necessary actions. Please see the following code snippet for your reference.
|
<imageEditor:SfImageEditor x:Name="imageEditor" Source="imageeditordesktop.png" ToolbarItemSelected = "OnImageEditorToolbarItemSelected" />
private void OnImageEditorToolbarItemSelected(object sender, ToolbarItemSelectedEventArgs e) {
}
|
We have prepared a sample demonstrating this. Please see the attached sample for your reference.
If you require further assistance, feel free to let us know.
Regards,
Vidyalakshmi M
When I do this on the OnDisappearing():
Stream stream = await Drawing.GetImageStream();
I get an exception:
"Value does not fall within the expected range."
For the second part, I am not using the toolbar so I assume there is not another event available?
Hi Phunction,
We have reviewed the image stream retrieval in the `OnDisappearing` method and have found it to be working correctly. To assist you further, we have attached a sample for your reference. Please test our sample and let us know if the issue persists. If it does, please share your sample or modify ours to replicate the problem in your scenario. Additionally, please provide a video demonstrating the issue.
Regarding your inquiry about events like PenUp or DrawingEnd, you can utilize the AnnotationSelected and AnnotationUnSelected events. When you add the pen in a button click, the AnnotationSelected event will be triggered. Similarly, when you save changes in a button click, the AnnotationUnselected event will be triggered. This allows you to use these events without relying on the toolbar. Please note that these events will be triggered for all annotations. We have prepared a simple sample demonstrating this. Please see the attached sample for your reference.
Regards,
Vidyalakshmi M.
The crash in ondisappearing happens when the window is closed.
In your example, if you run the app, draw a line then click the X to close, it will give the error.
This also happens if the drawing is on a child page and you press the back button <-
Hi Phunction,
After investigation, we were able to replicate the reported issue regarding the use of the GetImageStream method in the OnDisappearing method. The reason for the crash is that the GetImageStream method is an asynchronous method that runs in the background thread. When the application is closed, this background thread is also terminated, resulting in the disposal of the available stream and hence the crash occurs.
To resolve this issue, we suggest retrieving the image stream once you finish editing the image. You can achieve this by getting the stream of the image when the image editor is loaded or by retrieving the image stream each time you finish editing the image. Please see the following code snippets for reference.
|
private async void OnImageEditorImageLoaded(object sender, EventArgs e) { using Stream imageStream = await imageEditor.GetImageStream(); this.imageBytes = this.GetImageBytesFromStream(imageStream); }
private async void imageEditor_AnnotationUnselected(object sender, AnnotationUnselectedEventArgs e) { await Task.Delay(500); using Stream imageStream = await imageEditor.GetImageStream(); this.imageBytes = this.GetImageBytesFromStream(imageStream); }
|
Please note that we have added a delay in the AnnotationUnselected event to allow time for the stream to process after unselecting an annotation. This delay ensures that you can safely retrieve the image stream.
Additionally, we recommend converting the stream into bytes and storing these bytes to avoid memory issues. Here's a code snippet for converting the stream into bytes:
|
private byte[] GetImageBytesFromStream(Stream input) { input.Position = 0; var buffer = new byte[16 * 1024]; using (MemoryStream ms = new MemoryStream()) { int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0) { ms.Write(buffer, 0, read); } return ms.ToArray(); } }
|
In the OnDisappearing event, you can then retrieve the stream from the bytes as shown below:
|
protected override void OnDisappearing() { var stream = this.GetImageStreamFromBytes(); base.OnDisappearing(); }
private Stream GetImageStreamFromBytes() { return new MemoryStream(this.imageBytes); }
|
We have prepared a simple sample demonstrating this approach. Please find the attached sample for your reference. Kindly review the sample and let us know if it resolves your issue.
If you need any further assistance, please don't hesitate to contact us. We are here to help.
Regards,
Vidyalakshmi M.