问题
I have collection of products from web service, I preview this product in Grid View, but I get the images of the products as Base64 strings. How can I convert it to images and bind it to the images in the Grid View?
Any piece of code that will help me in this issue.
回答1:
In WPF/Metro/Silverlight, Image is a UI control. Its source is set to BitmapSource. BitmapSource is a data structure to hold image data.
Following is the code to retrieve BitmapImage from byte array.
public BitmapImage ImageFromBuffer(Byte[] bytes)
{
MemoryStream stream = new MemoryStream(bytes);
BitmapImage image = new BitmapImage();
image.SetSource ( stream.AsRandomAccessStream());
return image;
}
Note that stream.AsRandomAccessStream is not available in API It is an extension method. I found it from response of IDWMaster to this SO question
Following is the code for extension method
public static class MicrosoftStreamExtensions
{
public static IRandomAccessStream AsRandomAccessStream(this Stream stream)
{
return new RandomStream(stream);
}
}
class RandomStream : IRandomAccessStream
{
Stream internstream;
public RandomStream(Stream underlyingstream)
{
internstream = underlyingstream;
}
public IInputStream GetInputStreamAt(ulong position)
{
internstream.Position = (long)position;
return internstream.AsInputStream();
}
public IOutputStream GetOutputStreamAt(ulong position)
{
internstream.Position = (long)position;
return internstream.AsOutputStream();
}
public ulong Size
{
get
{
return (ulong)internstream.Length;
}
set
{
internstream.SetLength((long)value);
}
}
public bool CanRead
{
get { return internstream.CanRead; }
}
public bool CanWrite
{
get { return internstream.CanWrite; }
}
public IRandomAccessStream CloneStream()
{
//HACK, this is not clone, proper implementation is required, returned object will share same internal stream
return new RandomStream(this.internstream);
}
public ulong Position
{
get { return (ulong)internstream.Position; }
}
public void Seek(ulong position)
{
internstream.Seek((long)position, SeekOrigin.Current);
}
public void Dispose()
{
internstream.Dispose();
}
public Windows.Foundation.IAsyncOperationWithProgress<IBuffer, uint> ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)
{
throw new NotImplementedException();
}
public Windows.Foundation.IAsyncOperation<bool> FlushAsync()
{
throw new NotImplementedException();
}
public Windows.Foundation.IAsyncOperationWithProgress<uint, uint> WriteAsync(IBuffer buffer)
{
throw new NotImplementedException();
}
}
Last 3 methods are not implemented
I have not tested but above should work in principal (may be after some refinement).
回答2:
This seem to work for me:
public static BitmapImage Base64StringToBitmap(string source)
{
var ims = new InMemoryRandomAccessStream();
var bytes = Convert.FromBase64String(source);
var dataWriter = new DataWriter(ims);
dataWriter.WriteBytes(bytes);
dataWriter.StoreAsync();
ims.Seek(0);
var img = new BitmapImage();
img.SetSource(ims);
return img;
}
Note I don't await anything, img.SetSource should take care of delayed load.
回答3:
below is the method that binds a Base64String
to an Image
control
convert the string to byte[] as follows
byte[] bytes = System.Convert.FromBase64String(thebase64string);
pass the byte[] and the Image control to which you want to bind the Image to.
public async void SetImageFromByteArray(byte[] data, Windows.UI.Xaml.Controls.Image image) { InMemoryRandomAccessStream raStream = new InMemoryRandomAccessStream(); DataWriter writer = new DataWriter(raStream); // Write the bytes to the stream writer.WriteBytes(data); // Store the bytes to the MemoryStream await writer.StoreAsync(); await writer.FlushAsync(); // Detach from the Memory stream so we don't close it writer.DetachStream(); raStream.Seek(0); BitmapImage bitMapImage = new BitmapImage(); bitMapImage.SetSource(raStream); image.Source = bitMapImage; }
回答4:
Try something like this:
byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
MemoryStream stream = new MemoryStream(encodedDataAsBytes.Length);
stream.Write(encodedDataAsBytes, 0, encodedDataAsBytes.Length);
Image img = Image.FromStream(stream);
I haven't worked with metro, so I can't help with binding to grid.. Best regards.
来源:https://stackoverflow.com/questions/10516856/how-to-convert-base64-string-to-image-then-bind-it-to-gridview-in-a-metro-style