Convert BitmapImage or IRandomAccessStream to byte array in Windows 10 UAP - c#

Who can help me. I don't understand how i can convert BitmapImage or IRandomAccessStream to byte array.
I try:
foreach (StorageFile file in files)
{
BitmapImage src = new BitmapImage();
using (IRandomAccessStream stream = await file.OpenReadAsync())
{
await src.SetSourceAsync(stream);
WriteableBitmap bitMap = new WriteableBitmap(src.PixelWidth, src.PixelHeight);
await bitMap.SetSourceAsync(stream);
}
}
then i have WriteableBitmap and try this:
private byte[] ImageToByeArray(WriteableBitmap wbm)
{
using (Stream stream = wbm.PixelBuffer.AsStream())
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
}
but it's don't work for me ;(

This should do it:
async Task<byte[]> Convert(IRandomAccessStream s)
{
var dr = new DataReader(s.GetInputStreamAt(0));
var bytes = new byte[s.Size];
await dr.LoadAsync((uint)s.Size);
dr.ReadBytes(bytes);
return bytes;
}

I used this solution in my WPF applications to save images in database as byte[]. It should also work in your case.
public static byte[] ImageToString(System.Windows.Media.Imaging.BitmapImage img) {
System.IO.MemoryStream stream = new System.IO.MemoryStream();
System.Windows.Media.Imaging.BmpBitmapEncoder encoder = new System.Windows.Media.Imaging.BmpBitmapEncoder();
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create((System.Windows.Media.Imaging.BitmapSource)img));
encoder.Save(stream);
stream.Flush();
return stream.ToArray();
}

Related

Converting ImageSource to String on C# WPF

ESRI Symbology library is slow and sometimes take longer time than expected.
I wish to serialize a selected range of ImageSource to a cache, string in the memory or file.
I have searched the web but not much on ImageSource.
An interesting thing I have found is "ImageSourceValueSerializer".
Being a 3 months old baby in WPF, I am not so sure how to go about this.
here's how I got the ImageSource:
MultilayerPointSymbol multiLayerSym = await result.GetSymbolAsync() as MultilayerPointSymbol;
RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();
ImageSource symbolImage = await swatch.ToImageSourceAsync();
Tested Clemen's, the routine:
MultilayerPointSymbol multiLayerSym = await result.GetSymbolAsync() as MultilayerPointSymbol;
RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();
ImageSource symbolImage = await swatch.ToImageSourceAsync();
byte[] b = ImageSourceBinary(symbolImage);
ImageSource test = BinaryImageSource(b);
In the class:
private byte[] ImageSourceBinary(ImageSource imageSrc)
{
if (imageSrc is BitmapSource bitmapSource)
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (MemoryStream stream = new MemoryStream())
{
encoder.Save(stream);
return stream.ToArray();
}
}
return null;
}
private ImageSource BinaryImageSource(byte[] bytes)
{
using (MemoryStream stream = new MemoryStream(bytes))
{
PngBitmapDecoder decoder = new PngBitmapDecoder(stream, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.Default);
BitmapFrame bf = decoder.Frames[0];
if (bf is ImageSource imagesource)
return imagesource;
return null;
}
}
The outcome, no image! :(
Check if the ImageSource is a BitmapSource and encode the BitmapSource by one of the BitmapEncoders. Encode into a MemoryStream or a FileStream.
private byte[] ImageSourceToByteArray(ImageSource imageSrc)
{
if (symbolImage is BitmapSource bitmapSource)
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return stream.ToArray();
}
}
return null;
}
In order to decode an image from a byte array, do not explictly use a specific BitmapDecoder. Better rely on automatic decoder selection, like shown below. It is also important to set BitmapCacheOption.OnLoad when the stream is closed right after decoding.
private ImageSource ByteArrayToImageSource(byte[] bytes)
{
using (var stream = new MemoryStream(bytes))
{
return BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}

Error when convert byte array to BitmapImage in UWP

I want to get a BitmapImage when capture view's screenshot. So I start to get byte array data first, then convert to BitmapImage.
RenderTargetBitmap renderTarget = new RenderTargetBitmap();
await renderTarget.RenderAsync(swapChainPanel);
IBuffer pixelBuffer = await renderTarget.GetPixelsAsync();
await GetBitmapAsync(pixelBuffer.ToArray());
...
public static async Task<BitmapImage> GetBitmapAsync(byte[] data)
{
var bitmapImage = new BitmapImage();
try
{
using (var stream = new InMemoryRandomAccessStream())
{
using (var writer = new DataWriter(stream))
{
writer.WriteBytes(data);
await writer.StoreAsync();
await writer.FlushAsync();
writer.DetachStream();
}
stream.Seek(0);
await bitmapImage.SetSourceAsync(stream); // throw Exception
}
return bitmapImage;
}
catch (Exception e)
{
return null;
}
}
But it give error :
The component cannot be found. (Exception from HRESULT: 0x88982F50)
Please help me to find the problem.
Error when convert byte array to BitmapImage in UWP
The problem is you have not specific BitmapEncoder for BitmapImage when convertering. In general, we often use the following code to get BitmapImage from bytes.
_backAction = new Action<byte[]>(async (bytes) =>
{
InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream();
BitmapImage img = new BitmapImage();
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, stream);
encoder.SetPixelData(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Straight,
(uint)48,
(uint)32,
DisplayInformation.GetForCurrentView().LogicalDpi,
DisplayInformation.GetForCurrentView().LogicalDpi,
bytes);
await encoder.FlushAsync();
await img.SetSourceAsync(stream);
});

BitmapImage to byte[] - C# web

I need to convert a BitmapImage in a byte[] but I don't find how to do it in C# web.
I found examples but none of them work (JpegBitmapEncoder doesn't exist, BitmapImageObject.StreamSource doesn't exist, there isn't WriteableBitmap constructor with BitmapImage as parameter, Extensions.SaveJpeg(parameters) doesn't exist ...).
Examples I found:
Constructor new WriteableBitmap(bitmapImage) doesn't exist.
public static byte[] ConvertToBytes(this BitmapImage bitmapImage)
{
byte[] data;
// Get an Image Stream
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(bitmapImage);
// write an image into the stream
Extensions.SaveJpeg(btmMap, ms,
bitmapImage.PixelWidth, bitmapImage.PixelHeight, 0, 100);
// reset the stream pointer to the beginning
ms.Seek(0, 0);
//read the stream into a byte array
data = new byte[ms.Length];
ms.Read(data, 0, data.Length);
}
//data now holds the bytes of the image
return data;
}
new WriteableBitmap(img), System.Windows.Media.Imaging.Extensions.SaveJpeg don't exist.
public static byte[] ImageToBytes(BitmapImage img)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(img);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, img.PixelWidth, img.PixelHeight, 0, 100);
img = null;
return ms.ToArray();
}
}
imageSource.StreamSource doesn't exist.
public static byte[] ImageToByte(BitmapImage imageSource)
{
Stream stream = imageSource.StreamSource;
Byte[] buffer = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
buffer = br.ReadBytes((Int32)stream.Length);
}
}
return buffer;
}
JpegBitmapEncoder doesn't exist.
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
using(MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
Try with the using statement to a namespace in the beginning of your code.
Otherwise there should be some Nuget packages which you could install to achieve your goal.
using System.Drawing;
In Main method
Image img = Image.FromFile("path to the file");
var byteArray = ImageToByte(img);
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Try this
I think this will help...
public byte[] ConvertBitMapToByteArray(Bitmap bitmap)
{
byte[] result = null;
if (bitmap != null)
{
MemoryStream stream = new MemoryStream();
bitmap.Save(stream, bitmap.RawFormat);
result = stream.ToArray();
}
return result;
}
byte[] foo = System.IO.File.ReadAllBytes("bitmap path");
Or
byte[] foo;
Object obj = YourBitmap;
BinaryFormatter bf = new BinaryFormatter();
using (var ms = new MemoryStream())
{
bf.Serialize(ms, obj);
foo = ms.ToArray();
}
Or
ImageConverter foocon = new ImageConverter();
byte[] foo = (byte[])foocon.ConvertTo(YourBitmap, typeof(byte[]));
Or
MemoryStream ms = new MemoryStream();
Bitmap.Save(ms, YourBitmap.RawFormat);
byte[] foo = ms.ToArray();
Finally, it seems that, obviously, it missed some libraries but we are limited with our application, so we decided to recover our pictures by another way. Anyway, thank you all.

How to edit a BitmapImage in Windows Phone 8.1 RT?

I have to edit a bitmapimage at pixel level. But Writeablebitmap Class for windows phone doesn't have WritePixels function.
I hope this is something you are looking for.
I had the same problem and managed to solve it with this. If you need some other explanation please leave a comment.
private static async Task<BitmapImage> ConvertImage(byte[] imageSource)
{
if (imageSource == null)
{
return null;
}
MemoryStream memoryStream = new MemoryStream(imageSource);
using (IRandomAccessStream randomAccessStream = memoryStream.AsRandomAccessStream())
{
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(randomAccessStream);
PixelDataProvider provider = await decoder.GetPixelDataAsync(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, new BitmapTransform(), ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
byte[] pixels = provider.DetachPixelData();
//Each Pixel is composed of 4 bytes [0]: Blue, [1]: Green, [2]: Red, [3] Alpha
//Do Here your magic with this pixels byte array
using (InMemoryRandomAccessStream memoryRandomAccessStream = new InMemoryRandomAccessStream())
{
var imageBytes = await EncodeImageBytes(memoryRandomAccessStream, decoder, pixels);
using (InMemoryRandomAccessStream stream = new InMemoryRandomAccessStream())
{
BitmapImage image = new BitmapImage();
await stream.WriteAsync(imageBytes.AsBuffer());
stream.Seek(0);
image.SetSource(stream);
return image;
}
}
}
}
private static async Task<byte[]> EncodeImageBytes(InMemoryRandomAccessStream memoryRandomAccessStream, BitmapDecoder decoder, byte[] pixels)
{
BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, memoryRandomAccessStream);
encoder.SetPixelData(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, decoder.PixelWidth, decoder.PixelHeight, 96, 96, pixels);
await encoder.FlushAsync();
var imageBytes = new byte[memoryRandomAccessStream.Size];
await memoryRandomAccessStream.ReadAsync(imageBytes.AsBuffer(), (uint) memoryRandomAccessStream.Size, InputStreamOptions.None);
return imageBytes;
}

Bitmap to Base64String

i am trying to convert a bitmap to a base64 string.i can convert to from string to bitmap...but it seems like there is a problem when converting from bitmap to string.I was hoping you guys could give me a hand
public static string BitmapToString(BitmapImage image)
{
Stream stream = image.StreamSource ;
Byte[] buffer = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
buffer = br.ReadBytes((Int32)stream.Length);
}
}
return Convert.ToBase64String(buffer);
}
it gets a ArgumentNullException was unhandled
Value cannot be null.
Parameter name: inArray
when returning Convert.ToBase64String(buffer)
Help?
Try this alternative:
public string BitmapToBase64(BitmapImage bi)
{
MemoryStream ms = new MemoryStream();
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bi));
encoder.Save(ms);
byte[] bitmapdata = ms.ToArray();
return Convert.ToBase64String(bitmapdata);
}
In your solution, it is not necessary that StreamSource will always have value if it is loaded using a Uri.
First of all, it is necessary to save BitmapImage data into memory using some bitmap encoder (PngBitmapEncoder for example).
public static byte[] EncodeImage(BitmapImage bitmapImage)
{
using (MemoryStream memoryStream = new MemoryStream())
{
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
encoder.Save(memoryStream);
return memoryStream.ToArray();
}
}
Then just encode the binary data with Base64-encoding.
const string filePath = #"...";
const string outFilePath = #"...";
const string outBase64FilePath = #"...";
// Constuct test BitmapImage instance.
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = File.OpenRead(filePath);
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
// Convert BitmapImage to byte array.
byte[] imageData = EncodeImage(bitmapImage);
File.WriteAllBytes(outFilePath, imageData);
// Encode with Base64.
string base64String = Convert.ToBase64String(imageData);
// Write to file (for example).
File.WriteAllText(outBase64FilePath, base64String);

Categories

Resources