After writing the application for Windows Phone, I wanted to bring the same feature with Windows 8 Metro but unfortunately, metro didn’t support the same converter for the reason that BitmapImage can no more read from Stream but only from IRandomAccessStream. I was very much disappointed with the Metro 8 API for having different design for different platforms.
Well since I have to anyway come up with a solution, I burned the mid night oil and wrote my own class. To start with, IRandomAccessStream will be generated using Metro API only when you are using a picker to open a file and there is no way at least I could find out to generate a stream other than writing my own by implementing IRandomAccessStream.
So below is the implementation.
public class RandomStream : IRandomAccessStream { private Stream streamValue; public RandomStream(Stream stream) { this.streamValue = stream; } public RandomStream(byte[] bytes) { this.streamValue = new MemoryStream(bytes); } public IInputStream GetInputStreamAt(ulong position) { if ((long)position > this.streamValue.Length) { throw new IndexOutOfRangeException(); } this.streamValue.Position = (long)position; return this.streamValue.AsInputStream(); } public IOutputStream GetOutputStreamAt(ulong position) { if ((long)position > this.streamValue.Length) { throw new IndexOutOfRangeException(); } this.streamValue.Position = (long)position; return this.streamValue.AsOutputStream(); } public ulong Size { get { return (ulong)this.streamValue.Length; } set { this.streamValue.SetLength((long)value); } } public bool CanRead { get { return true; } } public bool CanWrite { get { return true; } } public IRandomAccessStream CloneStream() { throw new NotSupportedException(); } public ulong Position { get { return (ulong)this.streamValue.Position; } } public void Seek(ulong position) { this.streamValue.Seek((long)position, 0); } public void Dispose() { this.streamValue.Dispose(); } public Windows.Foundation.IAsyncOperationWithProgress ReadAsync(IBuffer buffer, uint count, InputStreamOptions options) { throw new NotSupportedException(); } public Windows.Foundation.IAsyncOperation FlushAsync() { throw new NotImplementedException(); } public Windows.Foundation.IAsyncOperationWithProgress WriteAsync(IBuffer buffer) { throw new NotImplementedException(); } }
All the methods which is not implemented is not required for the converter to operate. If you are planning to use this class for some other operations, then you might need to implement them as per need.
public class BytesToImageConverter : IValueConverter { public object Convert(object value, Type typeName, object parameter, string language) { if (value != null && value is byte[]) { byte[] bytes = value as byte[]; Stream stream = new MemoryStream(bytes); BitmapImage image = new BitmapImage(); image.SetSource(new RandomStream(stream)); return image; } return null; } public object ConvertBack(object value, Type typeName, object parameter, string language) { throw new NotImplementedException(); } }
Below is the converter which will help you convert the byte array to BitmapImage.
Implement the converter in your xaml as below considering that you have added the converter as a resource in the dictionary.
Thanks for posting this.
It could have been so simple.
Nice solution! 🙂
try this one, I think is better
image = new BitmapImage();
InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream();
ms.AsStreamForWrite().Write(imageBytes, 0, imageBytes.Length);
ms.Seek(0);
image.SetSource(ms);
Hey I wanted to use it in C++/WinRT for Windows Store App.Do you have C++ version of this code.I wanted to use it in C+ code.
Vikram I am no C++ programmer and therefore I will be as good as you finding out a conversion tool for the same. Good luck.