Convert System.Windows.Media.ImageSource to ByteArray - c#

is there a way to convert a ImageSource object to byte array?
I have an ImageSource object bound to a WPF window, i can convert a byte array from the data base and convert it to ImageSource but i can't do it the reverse way.
Thx in advance.
Edit: I tried to convert ImageSource as BitmapImage but got a null object.

Even if your ImageSource is not a BitmapImage you may still successfully cast it to BitmapSource, which is the base class of all WPF bitmap classes like BitmapImage, BitmapFrame, WriteableBitmap, RenderTargetBitmap etc. (see here).
So in case your ImageSource is actually a BitmapSource (and not a DrawingImage or a D3DImage), the following method converts it to a byte array by using the specified BitmapEncoder (e.g. a PngBitmapEncoder):
public byte[] ImageSourceToBytes(BitmapEncoder encoder, ImageSource imageSource)
{
byte[] bytes = null;
var bitmapSource = imageSource as BitmapSource;
if (bitmapSource != null)
{
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
bytes = stream.ToArray();
}
}
return bytes;
}

Related

Using SkiaSharp.SKBitmap image as the ImageSource for a Button in Xamarin

I am attempting to use/convert the SKBitmap image as/to an ImageSource object in order to use the aforementioned image in a Button by assignment to its ImageSource property but, for the life of me, cannot figure out how to convert an SKBitmap object to an ImageSource.
Searching the web only yielded the articles/issues on converting an ImageSource to SKBitmap but not the converse.
Thanks in advance.
You could try this:
SKBitmap bitmap = ...;
// create an image COPY
//SKImage image = SKImage.FromBitmap(bitmap);
// OR
// create an image WRAPPER
SKImage image = SKImage.FromPixels(bitmap.PeekPixels());
// encode the image (defaults to PNG)
SKData encoded = image.Encode();
// get a stream over the encoded data
Stream stream = encoded.AsStream();
img.Source = ImageSource.FromStream(()=> stream);
The ImageSource property of the Button class is of ImageSource type, whose value can be set to that of a string representing the path of an image either via assigning the string to the property or using the ImageSource.FromFile() method. As the ImageSource type cannot be used with SKBitmap images, the image represented by the SKBitmap object can be saved to the disk (preferably in the application cache) and the path to the saved image can be used to initialize the concerned ImageSource object.
SKBitmap bitmap;
SKImage image = SKImage.FromBitmap(bitmap);
SKData encodedData = image.Encode(SKEncodedImageFormat.Png, 100);
string imagePath = Path.Combine(FileSystem.CacheDirectory, "image.png");
bitmapImageStream = File.Open(imagePath,
FileMode.Create,
FileAccess.Write,
FileShare.None);
encodedData.SaveTo(bitmapImageStream);
bitmapImageStream.Flush(true);
bitmapImageStream.Dispose();
ImageSource imgSrc;
imgSrc = ImageSource.FromFile(imagePath);
// or imgSrc = imagePath;

display an image retrieved from its URI

I have some problems while trying to serialize an object containing a BitmapSource field.
In fact, at the beginning, I had an ImageSource but it seems not to be serializable.
So I tried to use the associated property to store a string and to convert & convert back the image to/from the string.but no image is displayed now :-(
here is the XAML image tag:
<Image
x:Name="bookCover"
Grid.Row="0"
Grid.RowSpan="1"
Grid.Column="0"
MaxWidth="200"
MaxHeight="320"
Margin="5"
Source="{Binding Image}" SizeChanged="bookCover_SizeChanged" >
</Image>
here is the Image property & field in the model class:
public string _image;
public BitmapSource Image
{
get => Base64ToImage(_image);
set
{
_image =ImageToBase64(value);
OnPropertyChanged("Image");
}
}
and their associated methods:
public static string ImageToBase64(BitmapSource bitmap)
{
var encoder = new JpegBitmapEncoder();
var frame = BitmapFrame.Create(bitmap);
encoder.Frames.Add(frame);
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return Convert.ToBase64String(stream.ToArray());
}
}
public static BitmapSource Base64ToImage(string base64)
{
byte[] bytes = Convert.FromBase64String(base64);
using (var stream = new MemoryStream(bytes))
{
return BitmapFrame.Create(stream);
}
}
and here my program retrieves an image from internet via its URI and stores it:
var myUri=new Uri(book0.LargeImage.URL);
bookToInsert.Image = new BitmapImage(myUri);
thank you.
When you create a BitmapSource from a stream that is closed immediately after creation, you have to set BitmapCacheOption.OnLoad. Otherwise the stream would have to be kept open until the BitmapSource is actually used, e.g. displayed in an Image element.
public static BitmapSource Base64ToImage(string base64)
{
using (var stream = new MemoryStream(Convert.FromBase64String(base64)))
{
return BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
A couple of notes:
base64 encoding and decoding seems unnecessary. Better serialize a byte array.
Do not initially create a BitmapImage from the URL. Better directly get the image buffer by a web request.
You can bind the Source property of an Image element not only to an ImageSource, but also to a string, Uri or byte array. So your property may be declared as byte[] Image.
Try a much simpler view model like this:
public class ViewModel : INotifyPropertyChanged
{
private byte[] image;
public byte[] Image
{
get => image;
set
{
image = value;
OnPropertyChanged(nameof(Image));
}
}
}
and set the Image property like this:
var webClient = new WebClient();
viewModel.Image = webClient.DownloadData(book0.LargeImage.URL);
Or asynchronously:
var httpClient = new HttpClient();
viewModel.Image = await httpClient.GetByteArrayAsync(book0.LargeImage.URL);

How to convert BitmapImage to StdPicture

I have a BitmapImage object loaded with an icon, I need to convert that to StdPicture. How do I do that ?
I found tons of examples on how to convert System.Drawing.Image to StdPicture but nothing for System.Windows.Media.Imaging.BitmapImage to StdPicture.
Do I have to first convert it to Winforms Image and then to StdPicture ? Sounds a bit silly to me.
I am assuming stdPicture you mean Bitmap.. So here we go.
private Bitmap BitmapImageToBitmap(BitmapImage bitmapImage)
{
using (MemoryStream os = new MemoryStream())
{
BitmapEncoder encoder = new BmpBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
encoder.Save(os);
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(os);
return new Bitmap(bitmap);
}
}

String[] to image gets failed

I have an array of string from which I need to Draw an image in Windows forms.
I've done the following two steps:
converted the string array into memory stream.
and used the following code:
Image image = Image.FromStream(memory stream);
But it always returns null.
You can get image from byte array:
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
Be aware with formats. For example, Silverlight and WPF support only JPEG or PNG. Otherwise will get an exception.

How to convert type 'system.windows.media.imagesource' to 'system.drawing.image' or byte[] in C#?

I am doing a project in which a built in class for DICOM giving me the ImageSource,I want to use that ImageSource in My silverlight Image control. This conversion I am doing through WCF services. I found WCF does not support ImageSource, so I need to convert the output of built in class into Image or else in byte[]. So that I can send that output to Silverlight and in Silverlight client I'll reconvert it to ImageSource and can assign it to Image Control easily.
I googled for this but I did not find any help in there. Can anybody help me to fix this problem or provide me any alternate solution for this. Any help will be appreciated, Thanks in advance.
Note:- I do not have any permission for code modification on the built in class. As its a third party library.
UPDATE:-
Brief Description:
I have a class let say GetImageSource and in that I have a method say giveImgSource(). Now my questions is:
In WCF I have to call this method and after getting ImageSource from this method I need to pass it to my silverlight Client. As WCF doesn't know about ImageSource, so I need to convert the output of this method to some one out of the following or any alternate if you knows:
byte[]
Image
FileStream
MemoryStream etc
Is it a png image? Then use this to convert to byte[]:
var image = (BitmapSource)value;
BitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
return ms.ToArray();
}
UPDATE:
Decoding:
var bytes = (byte[])value;
var image = new BitmapImage();
image.BeginInit();
if (bytes == null)
{
// Processing null case
}
else
{
using (var ms = new MemoryStream(bytes))
{
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
}
}
return image;
Please refer to the below links for converting ImageSource to byte[]. They use the BitmapSource and WriteableBitmap classes which are available under PresentationCore library.
(1) How to Convert ImageSource to byte[]?
(2) How to Convert ImageSource to byte[] and back to ImageSource?
Hope that it will solve your problem.
The following two helper methods should be able to do the trick:
public BitmapImage ImageFromBuffer(Byte[] bytes)
{
MemoryStream stream = new MemoryStream(bytes);
BitmapImage image = new BitmapImage();
image.BeginInit();
image.StreamSource = stream;
image.EndInit();
return image;
}
public Byte[] BufferFromImage(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;
}

Categories