Xamarin SignaturePad Proper way of using UWP GetImageAsync? - xamarin

I'm using xamarin SignaturePad.
How to use GetImageAsync properly? because the output is not the same with my input.
I use this code:
var imageStream = await signature.GetImageStreamAsync(SignatureImageFormat.Jpeg);
public static byte[] ConvertStreamToByte(Stream stream)
{
if (stream != null)
{
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
return null;
}
Convert Byte[] to Image.
this.SignatureImage = ImageSource.FromStream(() => new MemoryStream(signatureData.Data));
My input on top.
Bottom pic is the retrieved data.
Is it misuse of GetImageAsync or Wrong Conversion? Help.

var imageStream = await signature.GetImageStreamAsync(SignatureImageFormat.Jpeg
, Color.Black, Color.White);
Need to add color for stroke and backround else it will default to black.

Related

How can I save an image in sqliteconnection xamarin forms [duplicate]

I have the following two methods that handles taking photos from a camera and picking photos from a library. They're both similar methods as at the end of each method, I get an ImageSource back from the Stream and I pass it onto another page which has an ImageSource binding ready to be set. These two method work perfectly. The next step now is to save the Image in SQLite so I can show the images in a ListView later on. My question for the XamGods (Xamarin Pros =), what is the best way to save image in SQLite in 2019? I have been in the forums for hours and I still don't have a tunnel vision on what I want to do. I can either
Convert Stream into an array of bytes to save in Sqlite.
Convert ImageSource into an array of bytes (messy/buggy).
Somehow retrieve the actual Image selected/taken and convert that into an array of bytes into SQLite
I'm sorry if my question is general, but Xamarin does not provide a clear-cut solution on how to save images in SQLite and you can only find bits and pieces of solutions throughout the forums listed below.
How to save and retrieve Image from Sqlite
Load Image from byte[] array.
Creating a byte array from a stream
Thank you in advance!
private async Task OnAddPhotoFromCameraSelected()
{
Console.WriteLine("OnAddPhotoFromCameraSelected");
var photo = await Plugin.Media.CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions() { });
var stream = photo.GetStream();
photo.Dispose();
if (stream != null)
{
ImageSource cameraPhotoImage = ImageSource.FromStream(() => stream);
var parms = new NavigationParameters();
parms.Add("image", cameraPhotoImage);
var result = await NavigationService.NavigateAsync("/AddInspectionPhotoPage?", parameters: parms);
if (!result.Success)
{
throw result.Exception;
}
}
}
private async Task OnAddPhotoFromLibrarySelected()
{
Console.WriteLine("OnAddPhotoFromLibrarySelected");
Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
if (stream != null)
{
ImageSource selectedImage = ImageSource.FromStream(() => stream);
var parms = new NavigationParameters();
parms.Add("image", selectedImage);
parms.Add("stream", stream);
var result = await NavigationService.NavigateAsync("/AddInspectionPhotoPage?", parameters: parms);
if (!result.Success)
{
throw result.Exception;
}
}
}
As Jason said that you can save image path into sqlite database, but if you still want to save byte[] into sqlite database, you need to convert stream into byte[] firstly:
private byte[] GetImageBytes(Stream stream)
{
byte[] ImageBytes;
using (var memoryStream = new System.IO.MemoryStream())
{
stream.CopyTo(memoryStream);
ImageBytes = memoryStream.ToArray();
}
return ImageBytes;
}
Then load byte[] from sqlite, converting into stream.
public Stream BytesToStream(byte[] bytes)
{
Stream stream = new MemoryStream(bytes);
return stream;
}
For simple sample, you can take a look:
Insert byte[] in sqlite:
private void insertdata()
{
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "sqlite1.db3");
using (var con = new SQLiteConnection(path))
{
Image image = new Image();
image.Content = ConvertStreamtoByte();
var result = con.Insert(image);
sl.Children.Add(new Label() { Text = result > 0 ? "insert successful insert" : "fail insert" });
}
}
Loading image from sqlite:
private void getdata()
{
var path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "sqlite1.db3");
using (var con = new SQLiteConnection(path))
{
var image= con.Query<Image>("SELECT content FROM Image ;").FirstOrDefault();
if(image!=null)
{
byte[] b = image.Content;
Stream ms = new MemoryStream(b);
image1.Source = ImageSource.FromStream(() => ms);
}
}
}
Model:
public class Image
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string FileName { get; set; }
public byte[] Content { get; set; }
}

FFImageLoading load bitmap into ImageViewAsync

How can I load a bitmap into an ImageViewAsync on Xamarin Android Native?
You can use LoadStream method, here you will see how to use this method:
ImageService.Instance
.LoadStream (GetStreamFromImageByte)
.Into (imageView);
Here is the GetStreamFromImageByte:
Task<Stream> GetStreamFromImageByte (CancellationToken ct)
{
//Here you set your bytes[] (image)
byte [] imageInBytes = null;
//Since we need to return a Task<Stream> we will use a TaskCompletionSource>
TaskCompletionSource<Stream> tcs = new TaskCompletionSource<Stream> ();
tcs.TrySetResult (new MemoryStream (imageInBytes));
return tcs.Task;
}
About imageInBytes, you can look here, convert the bitmap to byte[]:
MemoryStream stream = new MemoryStream();
bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream);
byte[] bitmapData = stream.ToArray();
I have posted my demo on github.

Xamarin : Convert image to Pdf format in Xamarin.forms

I am getting error width cannot be null , when passing image to inputstream.As i didn't find any alterante method . Basically i want to convert image to Pdf format in Xamarin.forms which supports UWP platform .
I am using xfinium pdf library for this.
public void ConvertJpegToPdf()
{
try
{
PdfFixedDocument document = new PdfFixedDocument();
Xfinium.Pdf.PdfPage page = document.Pages.Add();
page.Width = 800;
page.Height = 600;
var imageStream = GetStream();
PdfJpegImage jpeg = new PdfJpegImage(imageStream);//<-Error
PdfStandardFont helvetica = new PdfStandardFont(PdfStandardFontFace.Helvetica, 24);
PdfBrush brush = new PdfBrush(PdfRgbColor.Red);
page.Graphics.DrawImage(jpeg, 0, 0, page.Width, page.Height);
Stream pdfStream = null;
document.Save(pdfStream);
}
catch (Exception ex)
{
throw ex;
}
}
protected Stream GetStream()
{
byte[] byteArray = Encoding.UTF8.GetBytes("http://david.qservicesit.com/images/3.jpg");
MemoryStream stream = new MemoryStream(byteArray);
return stream;
}
Please suggest some alternate to do this
byte[] byteArray = Encoding.UTF8.GetBytes("http://david.qservicesit.com/images/3.jpg");
You could not get image stream in this way. The method you have used can only get the Bytes of string. For your scenario, you could use http client to acquire image stream. Please refer to the following code:
public async Task<Stream> GetStream()
{
HttpClient client = new HttpClient();
HttpResponseMessage res = await client.GetAsync(new Uri("http://david.qservicesit.com/images/3.jpg"));
Stream stream = await res.Content.ReadAsStreamAsync();
return stream;
}
public async Task ConvertJpegToPdf()
{
try
{
PdfFixedDocument document = new PdfFixedDocument();
Xfinium.Pdf.PdfPage page = document.Pages.Add();
page.Width = 800;
page.Height = 600;
var imageStream = await GetStream();
PdfJpegImage jpeg = new PdfJpegImage(imageStream);
PdfStandardFont helvetica = new PdfStandardFont(PdfStandardFontFace.Helvetica, 24);
PdfBrush brush = new PdfBrush(PdfRgbColor.Red);
page.Graphics.DrawImage(jpeg, 0, 0, page.Width, page.Height);
Stream pdfStream = new MemoryStream();
document.Save(pdfStream);
}
catch (Exception ex)
{
throw ex;
}
}

Loading Images from Web Api in Xamarin.Forms

I need to load a picture from a web api backend into my Xamarin.Forms app.
The picture is stored in an Azure Blob Storage.
This is my Web Api method:
[HttpGet("{id}")]
public HttpResponseMessage Get(int id)
{
// Retrieve storage account from connection string.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("ConnectionString");
// Create the blob client.
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
// Retrieve reference to a previously created container.
CloudBlobContainer container = blobClient.GetContainerReference("picturecontainer");
// Retrieve reference to a blob named "photo.jpg".
CloudBlockBlob blockBlob = container.GetBlockBlobReference("picture");
var stream = new MemoryStream();
blockBlob.DownloadToStream(stream);
Image image = Image.FromStream(stream);
MemoryStream memoryStream = new MemoryStream();
image.Save(memoryStream, ImageFormat.Jpeg);
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new ByteArrayContent(memoryStream.ToArray());
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
return result;
}
In my app I try to download the image bytes with the following code:
public App ()
{
_client = new HttpClient();
_client.MaxResponseContentBufferSize = 256000;
Button downloadImageBtn = new Button () {
Text = "Download Image",
};
var image = new Image() {
Source = ImageSource.FromUri (new Uri ("http://www.engraversnetwork.com/files/placeholder.jpg")),
Aspect = Aspect.AspectFit
};
downloadImageBtn.Clicked += async (object sender, EventArgs e) => {
var values = await handleClick (sender, e);
uploadPicButton.Text = values;
var imageBytes = await downloadPicture();
image.Source = ImageSource.FromStream(() => new MemoryStream(imageBytes));
};
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
image,
downloadImageBtn
}
}
};
}
private async Task<byte[]> downloadPicture()
{
var uri = new Uri (string.Format (RestUrl, "5"));
//return await _client.GetByteArrayAsync (uri);
var response = await _client.GetAsync (uri);
if (response.IsSuccessStatusCode) {
var content = await response.Content.ReadAsByteArrayAsync ();
return content;
}
throw new HttpRequestException ();
}
However when I click on the button, the placeholder image disappears.
Is there a problem when sending the image from the server or when receiving it in the app?
I'd not implement downloading Images manually.
If you want to load more images and/or allow to display a placeholder while loading, I recommend the FFImageLoading library. It offers nice functionality like downloading, caching, showing placeholder and error images and most important: down sampling the image to the target size. This is always a pain on android. Its available for native UI xamarin projects and for Xamarin.Froms.
You can bind strings that contain urls directly to the Source. The code would like like:
<ffimageloading:CachedImage
Source="http://thecatapi.com/?id=MTQ5MzcyNA">
</ffimageloading:CachedImage>
After blockblob.DownloadToStream line, try to set Position of the stream to 0. I'm not familiar with Azure API, but I think it may help.
Also ,try to use ReadAsStreamAsync instead of ReadAsByteArrayAsync in your downloadPicture function. Something like this:
var responseStream = await response.Content.ReadAsStreamAsync();
byte[] buf = new byte[512];
int bufSize;
while((bufSize = (await responseStream.ReadAsync(buf, 0, buf.Length))) > 0)
{
// store the received bytes to some buffer until the file is fully downloaded
}
Do you get all your content this way?

How can I pass a captured image to a canvas?

I have a class that uses the devices camera to capture an image. My aim is to pass the captured image to a canvas on another layout.
This layout will then be saved along with a note entered into a textbox.I have figured out how to save the note and title and allow it to be opened but I'm not sure how I would go about passing the captured image to the layout and saving it along with the note.
Does anyone have any advice or pointers as to how I would go about this?
At the moment this is how I'm attempting to read the image file back to the layout after it is saved,but I'm not sure how to read a file into the canvas so obviously this solution isn't working yet:
if (NavigationContext.QueryString.ContainsKey("note"))
{
string s2 = ".jpg";
string filename = this.NavigationContext.QueryString["note"];
if (!string.IsNullOrEmpty(filename)) {
using (var store = System.IO.IsolatedStorage.IsolatedStorageFile .GetUserStoreForApplication())
using (var stream = new IsolatedStorageFileStream(filename, FileMode.Open, FileAccess.ReadWrite, store))
/*
if(filename.Contains(s2))
{
StreamReader reader = new StreamReader(stream);
this.capturedNoteCanvas = reader.ReadToEnd();
this.noteNameTb.Text = filename; reader.Close();
}
else
*/
{
StreamReader reader = new StreamReader(stream);
this.noteDataTb.Text = reader.ReadToEnd();
this.noteNameTb.Text = filename; reader.Close();
}
}
}
What I'm thinking is something like this:
Working wit CameraCaptureTask and Bitmaps
//Taking a writableBitmap object from cameracapturetask
void cameracapturetask_Completed(object sender, PhotoResult e)
{
try
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
WritableBitmap wb=new WritableBitmap (bmp.PixelWidth,bmp.PixelHeight);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
saving wb in storage
using (MemoryStream stream = new MemoryStream())
{
wb.SaveJpeg(stream, (int)bmp.PixelWidth, (int)bmp.PixelHeight, 0, 100);
using (IsolatedStorageFileStream local = new IsolatedStorageFileStream(App.PageName, FileMode.Create, mystorage))
{
local.Write(stream.GetBuffer(), 0, stream.GetBuffer().Length);
}
}
//Taking a WritableBitmap from canvas
If your canvas is containing the image, and also the canvas it attributed with some height and width properties then
WritableBitmap wb= new WritableBitmap(canvascontrol,null);
takes the canvas and saves it inside a writablebitmap object which can then be used for further image manipulations.

Resources