I am developing a Windows Universal Application that will be running on ARM Architecture(RaspberryPi 3, OS: Windows IoT).
The problem i am facing is that UWP doesn't allow a lot of standard .Net libraries like "System.Drawing"
I currently have an IntPtr which contains the raw data for an image and i need to use it as Bitmap which of course is not possible in this scenario. Is there any possible alternative for it.
I have looked for BitmapImage but didn't found any solution to it.
I have also tried Converting the IntPtr to Byte[] but then Converting array to Image or BitmapImage is not Possible in UWP.
Please Go Easy on me as i am newbie on C# Programming.
All I want is any Type of Bitmap or Image from an IntPtr
Thanks in Advance!
To conver the IntPtr
to Byte[]
, we can use the Marshal.Copy
method. It copies data from a one-dimensional, managed 8-bit unsigned integer array to an unmanaged memory pointer.
Then we can use the WriteableBitmap
class to set the Byte[] to WriteableBitmap
.
The image source data of a WriteableBitmap is an underlying pixel buffer. PixelBuffer cannot be written to directly, however, you can use language-specific techniques to access the buffer and change its contents.
To access the pixel content from C# or Microsoft Visual Basic, you can use the AsStream extension method to access the underlying buffer as a stream.
For more info, refer Remarks of the WriteableBitmap.
To Convert the WriteableBitmap
to BitmapImage
, we should be able to encode the stream from WriteableBitmap
.
For example:
private byte[] managedArray;
private async void Button_Click(object sender, RoutedEventArgs e)
{
Windows.Storage.Streams.IRandomAccessStream random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/sunset.jpg")).OpenReadAsync();
Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(random);
Windows.Graphics.Imaging.PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
byte[] buffer = pixelData.DetachPixelData();
unsafe
{
fixed (byte* p = buffer)
{
IntPtr ptr = (IntPtr)p;
managedArray = new byte[buffer.Length];
Marshal.Copy(ptr, managedArray, 0, buffer.Length);
}
}
WriteableBitmap bitmap = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
await bitmap.PixelBuffer.AsStream().WriteAsync(managedArray, 0, managedArray.Length);
InMemoryRandomAccessStream inMemoryRandomAccessStream = new InMemoryRandomAccessStream();
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, inMemoryRandomAccessStream);
Stream pixelStream = bitmap.PixelBuffer.AsStream();
byte[] pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, pixels);
await encoder.FlushAsync();
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(inMemoryRandomAccessStream);
MyImage.Source = bitmapImage;
}