Wpf Image to Byte[]

Convert byte array to image in wpf

Hi this should be working:

    private static BitmapImage LoadImage(byte[] imageData)
{
if (imageData == null || imageData.Length == 0) return null;
var image = new BitmapImage();
using (var mem = new MemoryStream(imageData))
{
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}

WPF Image to byte[]

Real Solution... if want to save jpg images from an System.Windows.Control.Image when your database mapped field on your ORM is Byte[] / byte[] / Bynary

public byte[] getJPGFromImageControl(BitmapImage imageC)
{
MemoryStream memStream = new MemoryStream();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imageC));
encoder.Save(memStream);
return memStream.ToArray();
}

call as :

getJPGFromImageControl(firmaUno.Source as BitmapImage)

Hopes helps :)

What is the easiest way to display an image from Byte[]?

The BitmapImage.StreamSource property only accepts a stream that contains an encoded bitmap buffer, e.g. a PNG or JPEG.

In order to create a BitmapSource (the base class of BitmapImage) from raw pixel data, you may use the BitmapSource.Create() method. Depending on the number of bits per pixel, and the ordering of the alpha and color channels, you would also have to choose an appropriate PixelFormat.

Assuming an 8-bit grayscale format, you would create a BitmapSource like this:

private BitmapSource LoadImage(int width, int height, byte[] imageData)
{
var format = PixelFormats.Gray8;
var stride = (width * format.BitsPerPixel + 7) / 8;

return BitmapSource.Create(width, height, 96, 96, format, null, imageData, stride);
}

Of course you would also have to change the type of your property to BitmapSource (which is more flexible anyway, since you can still assign a BitmapImage).

public BitmapSource Picture { get; set; }

Wpf MVVM, How to convert ImageSource to byte array

Try this:

You can take other encoder as well.

private ImageSource mSnapshotTaken;
public ImageSource SnapshotTaken
{
get => mSnapshotTaken;
set
{
mSnapshotTaken = value;
SnapshotToByte = ImageSourceToBytes(mSnapshotTaken);
OnPropertyChanged("SnapshotTaken");
OnPropertyChanged("SnapshotToByte");
}
}

public byte[] SnapshotToByte { get; set; }

public byte[] ImageSourceToBytes(ImageSource imageSource)
{
byte[] bytes = null;
var bitmapSource = imageSource as BitmapSource;

if (bitmapSource != null)
{
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));

using (var stream = new MemoryStream())
{
encoder.Save(stream);
bytes = stream.ToArray();
}
}

return bytes;
}

REFERENCE: this & this

Display image from byte[ ]

Provided that you have a view model class that implements your IFile interface, and that its FileData property contains an encoded image buffer like a PNG or JPEG, you could directly bind to the property like this:

<Image Source="{Binding FileData}"/>

This is because WPF provides built-in, automatic type conversion from several source types, including byte[], to ImageSource.


The type conversion is performed by the class ImageSourceConverter, which is registered as TypeConverter

[TypeConverterAttribute(typeof(ImageSourceConverter))]
public abstract class ImageSource ...

and does something similar to this:

byte[] buffer = ...
ImageSource result;
using (var stream = new MemoryStream(buffer))
{
result = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}

How do I bind a Byte array to an Image in WPF with a value converter?

Thanks for all your help. I've now got it working. I'm still not sure exactly what the problem was.

This is how I put images into my database…

Private Sub ButtonUpload_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim FileOpenStream As Stream = Nothing
Dim FileBox As New Microsoft.Win32.OpenFileDialog()
FileBox.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
FileBox.Filter = "Pictures (*.jpg;*.jpeg;*.gif;*.png)|*.jpg;*.jpeg;*.gif;*.png|" & _
"All Files (*.*)|*.*"
FileBox.FilterIndex = 1
FileBox.Multiselect = False
Dim FileSelected As Nullable(Of Boolean) = FileBox.ShowDialog(Me)
If FileSelected IsNot Nothing AndAlso FileSelected.Value = True Then
Try
FileOpenStream = FileBox.OpenFile()
If (FileOpenStream IsNot Nothing) Then

Dim ByteArray As Byte()
Using br As New BinaryReader(FileOpenStream)
ByteArray = br.ReadBytes(FileOpenStream.Length)
End Using

Dim g As New ZackGraphic
g.Id = Guid.NewGuid
g.ImageData = ByteArray
g.FileSize = CInt(ByteArray.Length)
g.FileName = FileBox.FileName.Split("\").Last
g.FileExtension = "." + FileBox.FileName.Split(".").Last.ToLower
g.DateAdded = Now

Dim bmp As New BitmapImage
bmp.BeginInit()
bmp.StreamSource = New MemoryStream(ByteArray)
bmp.EndInit()
bmp.Freeze()

g.PixelWidth = bmp.PixelWidth
g.PixelHeight = bmp.PixelHeight

db.AddToZackGraphic(g)
db.SaveChanges()

End If
Catch Ex As Exception
MessageBox.Show("Cannot read file from disk. " & Ex.Message, "Add a New Image", MessageBoxButton.OK, MessageBoxImage.Error, MessageBoxResult.OK)
Finally
If (FileOpenStream IsNot Nothing) Then
FileOpenStream.Close()
End If
End Try
End If
End Sub

This is my value converter used to bind a Byte array to an Image…

Class BinaryImageConverter
Implements IValueConverter
Private Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
If value IsNot Nothing AndAlso TypeOf value Is Byte() Then
Dim ByteArray As Byte() = TryCast(value, Byte())
Dim bmp As New BitmapImage()
bmp.BeginInit()
bmp.StreamSource = New MemoryStream(ByteArray)
bmp.EndInit()
Return bmp
End If
Return Nothing
End Function
Private Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
Throw New Exception("The method or operation is not implemented.")
End Function
End Class

This is my XAML that uses the converter display the image…

<Window xmlns:local="clr-namespace:MyProjectName" ... >
<Window.Resources>
<local:BinaryImageConverter x:Key="imgConverter" />
</Window.Resources>
...
<Image Source="{Binding Path=ImageData, Converter={StaticResource imgConverter}}" />

BitMapImage to byte and reverse

I'm not really sure what you're doing with the getter-setter.

For getting a byte array from a file, I would have this:

public static byte[] FileToByteArray(string fileName)
{
byte[] fileData = null;

using (FileStream fs = new File.OpenRead(fileName))
{
var binaryReader = new BinaryReader(fs);
fileData = binaryReader.ReadBytes((int)fs.Length);
}
return fileData;
}

And once you have the bytes from that function, you can use ConvertToBitMapImage() and assign that to the Image.Source, like this:

byte[] bytes = FileToByteArray(fileName);
YourImage.Source = ConvertToBitMapImage(bytes);

I'm not sure why you would need to convert a BitmapImage into bytes, but you should be able to call your function directly for that:

BitmapImage bImg = new BitmapImage();
bImg.Source = ConvertToBitMapImage(bytes);
byte[] bytes = ImageToByte(bImg); // these should be the same bytes as went in

Set it up like this and step through the code to see where it snags. It's possible the bytes might need encoding when you grab it in ImageToByte().

But also, you don't just then set the byte[] directly to the IMAGES or this.IMAGES.IMAGE, because that isn't an Image object, it's a byte[]. Without knowing what your IMAGES model construct looks like with its property types, it's a little vague to know what is being set to what and why, but this seems like a bad idea to over-complicate what you should just do with function calls as it is needed, without a getter-setter and an IMAGES model in the way.

How to load and save image as byte array in a wpf mvvm project

You are using the WinForms Image class instead of the WPF BitmapSource. BitmapSource is a subclass of ImageSource, which is the type of the Image element's Source property.

Your converter should look like this:

public class ByteArrayToBitmapSourceConverter : IValueConverter
{
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture)
{
return ToBitmapSource(value as byte[]);
}

public object ConvertBack(
object value, Type targetType, object parameter, CultureInfo culture)
{
return ToByteArray(value as BitmapSource);
}

public static BitmapSource ToBitmapSource(byte[] buffer)
{
BitmapSource bitmap = null;

if (buffer != null)
{
using (var stream = new MemoryStream(buffer))
{
bitmap = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}

return bitmap;
}

public static byte[] ToByteArray(BitmapSource bitmap)
{
byte[] buffer = null;

if (bitmap != null)
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));

using (var stream = new MemoryStream())
{
encoder.Save(stream);
buffer = stream.ToArray();
}
}

return buffer;
}
}

It would however be a lot simpler to directly assign the frame buffer from the image file to the view model property like

viewModel.InputImage = File.ReadAllBytes(op.FileName);

You would not need your converter at all, because due to built-in type conversion, the Image.Source property can directly be bound to source properties of type string, Uri and byte[] (besides ImageSource).

So you could simply write

<Image Source="{Binding InputImage}" ... />


Related Topics



Leave a reply



Submit