Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
952 views
in Technique[技术] by (71.8m points)

xamarin.forms - Is there a cross-platform solution to ImageSource to byte[]?

I did researches and fell on this solution: http://forums.xamarin.com/discussion/22682/is-there-a-way-to-turn-an-imagesource-into-a-byte-array

Initial question: http://forums.xamarin.com/discussion/29569/is-there-a-cross-platform-solution-to-imagesource-to-byte#latest

We want to upload an image through a HTTP Post, here's what we tried:

HttpClient httpClient = new HttpClient ();
byte[] TargetImageByte = **TargetImageSource**; //How to convert it to a byte[]?
HttpContent httpContent = new ByteArrayContent (TargetImageByte);
httpClient.PostAsync ("https://api.magikweb.ca/debug/file.php", httpContent);

We also are having a hard time with the libraries we gotta include in the using clauses. It seems like using System.IO; works, but it doesn't give us access to classes like FileInfo or FileStream.

Anybody has any idea how this can be done aside from custom platform-specific converters? Possibly a Xamarin.Forms.ImageSource function toByte()?

Lemme know if you need more information.

TargetImageSource is a Xamarin.Forms.ImageSource.

ImageSource TargetImageSource = null;

Solution (Sten was right)

The ImageSource has to originate from another type to exist, that previous type can be converted to a byte[]. In this case, I use the Xamarin.Forms.Labs to take a picture and it returns a MediaFile in which a FileStream is accessible through the Source property.

//--Upload image
//Initialization
HttpClient httpClient = new HttpClient ();
MultipartFormDataContent formContent = new MultipartFormDataContent ();
//Convert the Stream into byte[]
byte[] TargetImageByte = ReadFully(mediaFile.Source);
HttpContent httpContent = new ByteArrayContent (TargetImageByte);
formContent.Add (httpContent, "image", "image.jpg");
//Send it!
await httpClient.PostAsync ("https://api.magikweb.ca/xxx.php", formContent);

App.RootPage.NavigateTo (new ClaimHistoryPage());

The function:

public static byte[] ReadFully(Stream input)
{
    using (MemoryStream ms = new MemoryStream()){
        input.CopyTo(ms);
        return ms.ToArray();
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think you're looking at it a bit backwards.

ImageSource is a way to provide a source image for Xamarin.Forms.Image to show some content. If you're already showing something on the screen your Image view was populated with data that came from elsewhere, such as a file or resource or stored in an array in memory... or however else you got that in the first place. Instead of trying to get that data back from ImageSource you can keep a reference to it and upload it as needed.

Maybe you can elaborate a bit on your particular need if you don't feel this solution applies to your case.

Pseudo code:

ShowImage(){
  ImageSource imageSource = ImageSource.FromFile("image.png"); // read an image file
  xf_Image.Source = imageSource; // show it in your UI
}

UploadImage(){
  byte[] data =  File.ReadAll("image.png");
  // rather than 
  // byte[] data = SomeMagicalMethod(xf_Image.Source);
  HttpClient.Post(url, data);
}

UPDATE:

Since you're taking a picture you can copy the MediaFile.Source stream into a memory stream, then you can reset the memory stream's position to point at the beginning of the stream so that you can read it once again and copy it to the http body.

Alternatively you can store the MediaFile.Source to a file and use ImageSource.FromFile to load it in the UI, and when necessary - you can copy the file's contents into an http post body.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...