Store and retrieve binary image in WPF - c#

I have saved Image in database as binary :
Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
if (fd.ShowDialog() == true)
{
ILogo.Source = new BitmapImage(new Uri(fd.FileName));
Stream stream = File.OpenRead(fd.FileName);
binaryImage = new byte[stream.Length];
stream.Read(binaryImage, 0, (int)stream.Length);
}
_merchantInfo.Logo = binaryImage;
I want to read the image and showing it image tool, I tried this:
_merchantInfo = new MerchantInfo();
_merchantInfo = _context.MerchantInfo.FirstOrDefault();
byte[] binaryPhoto = (byte[])_merchantInfo.Logo;
Stream stream = new MemoryStream(binaryPhoto);
_merchantLogo = new BitmapImage();
_merchantLogo.StreamSource = stream;
ILogo.Source = _merchantLogo;
No Error, But the image does not showing in image box :(
Is there error in my code?
Thanks.

Universal Binary Storage Method -> You must read all the bites of the picture/file and save them in a binary array.
OpenFileDialog FileDialog = new OpenFileDialog();
byte[] BinaryData = new byte[]{};
if(FileDialog.ShowDialog())
{
BinaryData = System.IO.File.ReadAllBytes(FileDialog.FileName);
}
Binary Retrieval(For Images Only in WPF) -> You must set an BitmapImage and store all the binary information within it with the help of a MemoryStream.
BitmapImage image = new BitmapImage();
byte[] binary = new byte{}; /* <--- The array where
we stored the binary
information of the picture*/
image.BeginInit();
image.StreamSource = new System.IO.MemoryStream(binary)
image.EndInit();
Universal Binary Retrieval and Binary File Upload Method ->
byte[] BinaryData = new byte[]{};
private void Download()
{
OpenFileDialog FileDialog = new OpenFileDialog();
if(FileDialog.ShowDialog())
{
BinaryData = System.IO.File.ReadAllBytes(FileDialog.FileName);
}
}
private void Save()
{
OpenFileDialog FileDialog = new SaveFileDialog();
if(FileDialog.ShowDialog())
{
using(System.IO.Stream stream = new File.Open(FileDialog.FileName, FileMode.Create))
{
using (var BinaryWriter = new BinaryWriter(stream))
{
BinaryWriter.Write(BinaryData);
BinaryWriter.Close();
}
}
}
}

Finally I have solved this, here is the code for store and retrieve the image in database as binary :
To store the image:
Microsoft.Win32.OpenFileDialog fd = new Microsoft.Win32.OpenFileDialog();
if (fd.ShowDialog() == true)
{
ILogo.Source = new BitmapImage(new Uri(fd.FileName));
Stream stream = File.OpenRead(fd.FileName);
binaryImage = new byte[stream.Length];
stream.Read(binaryImage, 0, (int)stream.Length);
}
_merchantInfo.Logo = binaryImage;
_context.SaveChanges();
Image retrieval and display:
merchantInfo = new MerchantInfo();
_merchantInfo = _context.MerchantInfo.FirstOrDefault();
byte[] binaryPhoto = (byte[])_merchantInfo.Logo;
Stream stream = new MemoryStream(binaryPhoto);
_merchantLogo = new BitmapImage();
_merchantLogo.BeginInit();
_merchantLogo.StreamSource = stream;
_merchantLogo.EndInit();
ILogo.Source = _merchantLogo;
Thanks for everyone helped me :)

i create this class and i am using it without any problems, try it and share it.
/// <summary>
/// created by Henka Programmer.
/// Class to make the converting images formats and data structs so easy.
/// This Class supporte the following types:
/// - BtimapImage,
/// - Stream,
/// - ByteImage
///
/// and the other option is image resizing.
/// </summary>
public class Photo
{
public BitmapImage BitmapImage;
public System.IO.Stream Stream;
public byte[] ByteImage;
public Photo(Uri PhotoUri)
{
this.BitmapImage = new BitmapImage(PhotoUri);
this.Stream = new MemoryStream();
this.Stream = this.BitmapImage.StreamSource;
this.ByteImage = StreamToByteArray(this.Stream);
}
public Photo(Bitmap Photo_Bitmap)
: this((ImageSource)(new ImageSourceConverter().ConvertFrom(Photo_Bitmap)))
{
/*
ImageSourceConverter c = new ImageSourceConverter();
byte[] bytes = (byte[])TypeDescriptor.GetConverter(Photo_Bitmap).ConvertTo(Photo_Bitmap, typeof(byte[]));
Photo ph = new Photo(bytes);*/
}
public Photo(ImageSource PhotoSource) : this(PhotoSource as BitmapImage) { }
public Photo(BitmapImage BitmapPhoto)
{
this.BitmapImage = BitmapPhoto;
this.ByteImage = GetByteArrayFromImageControl(BitmapPhoto);
this.Stream = new MemoryStream();
WriteToStream(this.Stream, this.ByteImage);
}
public Photo(string path)
{
try
{
this.Stream = System.IO.File.Open(path, System.IO.FileMode.Open);
this.BitmapImage = new BitmapImage();
BitmapImage.BeginInit();
BitmapImage.StreamSource = Stream;
BitmapImage.EndInit();
this.ByteImage = StreamToByteArray(this.Stream);
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
}
}
public Photo(byte[] byteimage)
{
this.ByteImage = new byte[byteimage.Length];
this.ByteImage = byteimage;
// WriteToStream(this.Stream, this.ByteImage);
//MemoryStream ms = new MemoryStream(byteimage);
this.Stream = new MemoryStream(byteimage);
}
private void WriteToStream(Stream s, Byte[] bytes)
{
using (var writer = new BinaryWriter(s))
{
writer.Write(bytes);
}
}
private byte[] StreamToByteArray(Stream inputStream)
{
if (!inputStream.CanRead)
{
throw new ArgumentException();
}
// This is optional
if (inputStream.CanSeek)
{
inputStream.Seek(0, SeekOrigin.Begin);
}
byte[] output = new byte[inputStream.Length];
int bytesRead = inputStream.Read(output, 0, output.Length);
Debug.Assert(bytesRead == output.Length, "Bytes read from stream matches stream length");
return output;
}
private BitmapImage BitmapImageFromBytes(byte[] bytes)
{
BitmapImage image = new BitmapImage();
using (System.IO.MemoryStream imageStream = new System.IO.MemoryStream())
{
imageStream.Write(ByteImage, 0, ByteImage.Length);
imageStream.Seek(0, System.IO.SeekOrigin.Begin);
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = imageStream;
image.EndInit();
//image.Freeze();
}
return image;
}
public BitmapImage GetResizedBitmap(int width, int height)
{
ImageSource imgSrc = CreateResizedImage(this.ByteImage, width, height);
return new Photo(GetEncodedImageData(imgSrc, ".jpg")).BitmapImage;
}
private ImageSource CreateResizedImage(byte[] imageData, int width, int height)
{
BitmapImage bmpImage = new BitmapImage();
bmpImage.BeginInit();
if (width > 0)
{
bmpImage.DecodePixelWidth = width;
}
if (height > 0)
{
bmpImage.DecodePixelHeight = height;
}
bmpImage.StreamSource = new MemoryStream(imageData);
bmpImage.CreateOptions = BitmapCreateOptions.None;
bmpImage.CacheOption = BitmapCacheOption.OnLoad;
bmpImage.EndInit();
Rect rect = new Rect(0, 0, width, height);
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
drawingContext.DrawImage(bmpImage, rect);
}
RenderTargetBitmap resizedImage = new RenderTargetBitmap(
(int)rect.Width, (int)rect.Height, // Resized dimensions
96, 96, // Default DPI values
PixelFormats.Default); // Default pixel format
resizedImage.Render(drawingVisual);
return resizedImage;
}
internal byte[] GetEncodedImageData(ImageSource image, string preferredFormat)
{
byte[] returnData = null;
BitmapEncoder encoder = null;
switch (preferredFormat.ToLower())
{
case ".jpg":
case ".jpeg":
encoder = new JpegBitmapEncoder();
break;
case ".bmp":
encoder = new BmpBitmapEncoder();
break;
case ".png":
encoder = new PngBitmapEncoder();
break;
case ".tif":
case ".tiff":
encoder = new TiffBitmapEncoder();
break;
case ".gif":
encoder = new GifBitmapEncoder();
break;
case ".wmp":
encoder = new WmpBitmapEncoder();
break;
}
if (image is BitmapSource)
{
MemoryStream stream = new MemoryStream();
encoder.Frames.Add(BitmapFrame.Create(image as BitmapSource));
encoder.Save(stream);
stream.Seek(0, SeekOrigin.Begin);
returnData = new byte[stream.Length];
BinaryReader br = new BinaryReader(stream);
br.Read(returnData, 0, (int)stream.Length);
br.Close();
stream.Close();
}
return returnData;
}
public byte[] GetByteArrayFromImageControl(BitmapImage imageC)
{
MemoryStream memStream = new MemoryStream();
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imageC));
encoder.Save(memStream);
return memStream.GetBuffer();
}
public ImageSource ToImageSource()
{
ImageSource imgSrc = this.BitmapImage as ImageSource;
return imgSrc;
}
public System.Windows.Controls.Image ToImage()
{
System.Windows.Controls.Image Img = new System.Windows.Controls.Image();
Img.Source = this.ToImageSource();
return Img;
}
}

Related

Cannot read a Bitmap image that I just saved in Base64

I try to load a picture (PNG), save-it in Base64 in a text file and reload it, but I only see gliberish pictures (black and white, very ugly, far from original!) after I load the picture from the text file.
Where's my problem?
BTW all examples (load the picture from image file, save to base64, load from base64) are all taken from SO questions.
First it's how a load the pictures from the PNG file:
try
{
var openFileDialog = new OpenFileDialog
{
CheckFileExists = true,
Multiselect = false,
DefaultExt = "png",
InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
};
if (openFileDialog.ShowDialog() == true)
{
Bitmap img;
using (var stream = File.Open(openFileDialog.FileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
img = new Bitmap(stream);
}
Logo.Source = BitmapToImageSource(img);
}
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString(), "An error occured", MessageBoxButton.OK, MessageBoxImage.Warning);
}
Save it to base64:
try
{
Bitmap img = BitmapSourceToBitmap2((BitmapSource) Logo.Source);
string base64String;
using (var stream = new MemoryStream())
{
img.Save(stream, ImageFormat.Png);
byte[] imageBytes = stream.ToArray();
base64String = Convert.ToBase64String(imageBytes);
}
string fileName = string.Format(CultureInfo.InvariantCulture, "image{0:yyyyMMddHHmmss}.txt",
DateTime.Now);
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), fileName);
using (var stream = File.Open(path, FileMode.CreateNew, FileAccess.Write, FileShare.None))
{
using (var writer = new StreamWriter(stream, System.Text.Encoding.UTF8))
{
writer.Write(base64String);
writer.Flush();
}
}
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString(), "An error occured", MessageBoxButton.OK, MessageBoxImage.Warning);
}
BitmapSourceToBitmap2:
int width = srs.PixelWidth;
int height = srs.PixelHeight;
int stride = width*((srs.Format.BitsPerPixel + 7)/8);
IntPtr ptr = IntPtr.Zero;
try
{
ptr = Marshal.AllocHGlobal(height*stride);
srs.CopyPixels(new Int32Rect(0, 0, width, height), ptr, height*stride, stride);
using (var btm = new Bitmap(width, height, stride, PixelFormat.Format1bppIndexed, ptr))
{
// Clone the bitmap so that we can dispose it and
// release the unmanaged memory at ptr
return new Bitmap(btm);
}
}
finally
{
if (ptr != IntPtr.Zero)
Marshal.FreeHGlobal(ptr);
}
And load it back from the file:
try
{
var openFileDialog = new OpenFileDialog
{
CheckFileExists = true,
Multiselect = false,
DefaultExt = "txt",
InitialDirectory =
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
};
if (openFileDialog.ShowDialog() == true)
{
string base64String;
using (FileStream stream = File.Open(openFileDialog.FileName, FileMode.Open))
{
using (var reader = new StreamReader(stream))
{
base64String = reader.ReadToEnd();
}
}
byte[] binaryData = Convert.FromBase64String(base64String);
var bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = new MemoryStream(binaryData);
bi.EndInit();
Logo.Source = bi;
}
}
catch (Exception exception)
{
MessageBox.Show(exception.ToString(), "An error occured", MessageBoxButton.OK, MessageBoxImage.Warning);
}
Here is a short code sequence that reads a JPG file into a byte array, creates a BitmapSource from it, then encodes it into a base64 string and writes that to file.
In a second step, the base64 string is read back from the file, decoded and a second BitmapSource is created.
The sample assumes that there is some XAML with two Image elements named image1 and image2.
Step 1:
var imageFile = #"C:\Users\Clemens\Pictures\DSC06449.JPG";
var buffer = File.ReadAllBytes(imageFile);
using (var stream = new MemoryStream(buffer))
{
image1.Source = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
var base64File = #"C:\Users\Clemens\Pictures\DSC06449.b64";
var base64String = System.Convert.ToBase64String(buffer);
File.WriteAllText(base64File, base64String);
Step 2:
base64String = File.ReadAllText(base64File);
buffer = System.Convert.FromBase64String(base64String);
using (var stream = new MemoryStream(buffer))
{
image2.Source = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
In case you need to encode an already existing BitmapSource into a byte array, use code like this:
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
buffer = stream.ToArray();
}

How to insert and retrieve an image from C# to/from a database? [duplicate]

This question already has answers here:
Byte array to image conversion
(14 answers)
Display image from byte[ ]
(1 answer)
Closed 5 years ago.
I'm new to WPF programming and Microsoft SQL server. I want to insert and retrieve an image to/from a database. I learned about converting an image (Windows.Controls.Image) to byte[] and storing it to a database, but I couldn't convert from byte[] to Image back to display it in a WPF window.
private Image byteArrayToImage(byte[] arr)
{
MemoryStream stream = new MemoryStream();
stream.Write(arr, 0, arr.Length);
stream.Position = 0;
System.Drawing.Image img = System.Drawing.Image.FromStream(stream); // Exception
BitmapImage returnImage = new BitmapImage();
returnImage.BeginInit();
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
returnImage.StreamSource = ms;
returnImage.EndInit();
Image ans = new Image();
ans.Source = returnImage;
return ans;
}
Output:
System.ArgumentException: 'Parameter is not valid.'
private byte[] imageToArray(System.Drawing.Image img) // Work well
{
MemoryStream ms = new MemoryStream();
FileInfo fi = new FileInfo(tempData); // File name
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] pic = ms.ToArray();
return pic;
}
first, create a static class for your PictureHelper. You must import the BitmapImage that is used in WPF, i think its the using System.Drawing.Imaging;
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Threading;
using Application = System.Windows.Forms.Application;
using Size = System.Drawing.Size;
public static class PictureHelper
{
public static BitmapImage GetImage(object obj)
{
try
{
if (obj == null || string.IsNullOrEmpty(obj.ToString())) return new BitmapImage();
#region Picture
byte[] data = (byte[])obj;
MemoryStream strm = new MemoryStream();
strm.Write(data, 0, data.Length);
strm.Position = 0;
Image img = Image.FromStream(strm);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
return bi;
#endregion
}
catch
{
return new BitmapImage();
}
}
public static string PathReturner(ref string name)
{
string filepath = "";
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = false;
openFileDialog.Filter = #"Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.gif;*.png;*.jpg";
openFileDialog.RestoreDirectory = true;
openFileDialog.Title = #"Please select an image file to upload.";
MiniWindow miniWindow = new MiniWindow();
miniWindow.Show();
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
filepath = openFileDialog.FileName;
name = openFileDialog.SafeFileName;
}
miniWindow.Close();
miniWindow.Dispose();
return filepath;
}
public static string Encryptor(this string safeName)
{
string extension = Path.GetExtension(safeName);
string newFileName = String.Format(#"{0}{1}{2}", Guid.NewGuid(), DateTime.Now.ToString("MMddyyyy(HHmmssfff)"), extension);
newFileName = newFileName.Replace("(", "").Replace(")", "");
return newFileName;
}
public static Bitmap ByteToBitmap(this byte[] blob)
{
MemoryStream mStream = new MemoryStream();
byte[] pData = blob;
mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
Bitmap bm = new Bitmap(mStream, false);
mStream.Dispose();
return bm;
}
public static byte[] BitmapToByte(this Image img)
{
byte[] byteArray = new byte[0];
using (MemoryStream stream = new MemoryStream())
{
img.Save(stream, ImageFormat.Png);
stream.Close();
byteArray = stream.ToArray();
}
return byteArray;
}
}
this is for retrieving the class (in my case, Candidate) with picture
public SortableBindingList<Candidate> RetrieveManyWithPicture(Candidate entity)
{
var command = new SqlCommand { CommandText = "RetrievePictureCandidates", CommandType = CommandType.StoredProcedure };
command.Parameters.AddWithValue("#CandidateId", entity.CandidateId).Direction = ParameterDirection.Input;
DataTable dt = SqlHelper.GetData(command); //this is where I retrieve the row from db, you have your own code for retrieving, so make sure it works.
var items = new SortableBindingList<Candidate>();
if (dt.Rows.Count <= 0) return items;
foreach (DataRow row in dt.Rows)
{
Candidate item = new Candidate();
item.CandidateId = row["CandidateId"].GetInt();
item.LastName = row["LastName"].GetString();
item.FirstName = row["FirstName"].GetString();
item.PictureId = row["PictureId"].GetInt();
item.PhotoType = PictureHelper.GetImage(row["Photo"]); //in my db, this is varbinary. in c#, this is byte[]
items.Add(item);
}
return items;
}
this is for uploading image from wpf to db which I used on my button
private void UploadButton_Click(object sender, EventArgs e)
{
string safeName = "";
string pathName = PictureHelper.PathReturner(ref safeName);
PictureViewModel vm = new PictureViewModel();
if (pathName != "")
{
safeName = safeName.Encryptor();
FileStream fs = new FileStream(pathName, FileMode.Open, FileAccess.Read);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, Convert.ToInt32(fs.Length));
fs.Close();
PicNameLabel.Text = safeName;
vm.Entity.Name = safeName; //this is the byte[]
Bitmap toBeConverted = PictureHelper.ByteToBitmap(data); //convert the picture before sending to the db
vm.Entity.Photo = PictureHelper.BitmapToByte(toBeConverted);
vm.Entity.Path = pathName;
CandidatePictureBox.Image = toBeConverted;
vm.Insert(vm.Entity);
}
}
this is the method to save the picture
public bool Insert(Picture entity)
{
var command = new SqlCommand();
try
{
command.CommandText = "AddPicture";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#Name", entity.Name).Direction = ParameterDirection.Input;
command.Parameters.AddWithValue("#Photo", entity.Photo).Direction = ParameterDirection.Input;
int result = SqlHelper.ExecuteNonQuery(command); //executenonquery will save the params to the db
return true;
}
catch (Exception)
{
return false;
}
}

Converting WPF BitmapImage to and from Base64 using JpegBitmapEncoder fails for loading JPG files

I want to store a WPF BitmapImage to XML. (I know this is not usually recommended but for my case, it makes sense as I want to embed all my resource to a single XML file besides other data I have).
So Here are my extension methods:
public static string ToBase64(this BitmapImage image, string format)
{
return Convert.ToBase64String(Encode(image, format));
}
public static Stream FromBase64(this string content)
{
var bytes = Convert.FromBase64String(content);
var stream = new MemoryStream();
stream.Write(bytes, 0, bytes.Length);
return stream;
}
private static byte[] Encode(BitmapImage bitmapImage, string format)
{
byte[] data = null;
BitmapEncoder encoder = null;
switch (format.ToUpper())
{
case "PNG": encoder = new PngBitmapEncoder();
break;
case "GIF": encoder = new GifBitmapEncoder();
break;
case "BMP": encoder = new BmpBitmapEncoder();
break;
case "JPG": encoder = new JpegBitmapEncoder();
break;
}
if (encoder != null)
{
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
ms.Seek(0, SeekOrigin.Begin);
data = ms.ToArray();
}
}
return data;
}
public static BitmapImage ToBitmapImage(this Stream stream)
{
try
{
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
return bitmap;
}
catch (Exception ex)
{
}
return null;
}
and here is my XML logics:
public async void LoadImage(Guid imageSourceGuid)
{
var sourceElement = await GetImageSource(imageSourceGuid);
if (sourceElement != null)
{
var data = sourceElement.Element("Value").Value;
Format = sourceElement.Attribute("Format").Value.ToUpper();
if (string.IsNullOrEmpty(data) == false)
{
using (var stream = data.FromBase64())
{
SetImage(stream.ToBitmapImage());
}
}
}
}
private void SetImage(BitmapImage bitmap)
{
this.ImageShape.Source = bitmap;
}
public async Task<XElement> GetImageSource(Guid id)
{
XElement result = null;
await Task.Run(() =>
{
var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment, IgnoreWhitespace = true, IgnoreComments = true, Async = true };
using (var reader = XmlReader.Create(FilePath, settings))
{
while (reader.Read())
{
if (reader.IsStartElement() && reader.Name == "ImageSource")
{
var att = reader.GetAttribute("Id");
if (att != null && Guid.Parse(att) == id)
{
result = XNode.ReadFrom(reader) as XElement;
break;
}
}
}
}
});
return result;
}
My XML file looks like:
<?xml version="1.0" encoding="utf-8"?>
<ImageSources>
<ImageSource Id="1b1e4ebc-484c-4f63-bbed-bf33430f85f2" Format="JPG" OriginalWidth="534" OriginalHeight="338">
<Value><![CDATA[....]]<Value>
</ImageSource>
</ImageSources>
...
But when I try to create a BitmapImage using ToBitmapImage method from the XML data I saved earlier I get "The image cannot be decoded. The image header might be corrupted." exception.
This only happens for JPG files I have no issue with PNG files at all.
You should rewind the MemoryStream after writing in your FromBase64 method:
public static Stream FromBase64(this string content)
{
var bytes = Convert.FromBase64String(content);
var stream = new MemoryStream();
stream.Write(bytes, 0, bytes.Length);
stream.Seek(0, SeekOrigin.Begin); // here
return stream;
}
Or construct it directly from the byte array:
public static Stream FromBase64(this string content)
{
return new MemoryStream(Convert.FromBase64String(content));
}
Afaik, JpegBitmapDecoder is the only BitmapDecoder in WPF that is affected by the source stream's actual Position.

How to download an image URL to switch to byte [] up and read it WP8 C#

for (int i = 3; i < 10; i++)
{
Uri uriimg = new Uri("http://i.msdn.microsoft.com/dynimg/IC53593" + i + ".jpg", UriKind.RelativeOrAbsolute);
SaveToLocalStorage(ImageToArray(uriimg), "anh1.jpg");
}
private byte[] ImagesToArray(Uri uriimg)
{
var image = new BitmapImage(uriimg);
MemoryStream ms = new MemoryStream();
image.ImageOpened += (s, e) =>
{
image.CreateOptions = BitmapCreateOptions.None;
WriteableBitmap wb = new WriteableBitmap(image);
wb.SaveJpeg(ms, image.PixelWidth, image.PixelHeight, 0, 100);
};
return ms.ToArray();
}
public async void SaveToLocalStorage(byte[] _imageBytes, string fileName)
{
if (_imageBytes == null)
{
return;
}
var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
if (!isoFile.DirectoryExists("dataImages"))
{
isoFile.CreateDirectory("dataImages");
}
string filePath = System.IO.Path.Combine("dataImages", fileName);
using (var stream = isoFile.CreateFile(filePath))
{
await stream.WriteAsync(_imageBytes, 0, _imageBytes.Length);
}
}
public ImageSource LoadFromLocalStorage(string fileName)
{
var isoFile = IsolatedStorageFile.GetUserStoreForApplication();
ImageSource imageSource = null;
if (isoFile.DirectoryExists("dataImages"))
{
string filePath = System.IO.Path.Combine("dataImages", fileName);
using (var imageStream = isoFile.OpenFile(filePath, FileMode.Open, FileAccess.Read))
{
imageSource = PictureDecoder.DecodeJpeg(imageStream);
}
}
return imageSource;
}
I get the value as byte [0] it can not convert to byte [].
The problem I see is in ImagesToArray. You create a new MemoryStream, subscribe to an event that sets it, and then immediately return it. I'm pretty sure that ms will have 0 bytes when it is returned.
You should instead not use image.ImageOpened, and just put that code in the ImagesToArray method directly:
private byte[] ImagesToArray(Uri uriimg)
{
var image = new BitmapImage(uriimg);
MemoryStream ms = new MemoryStream();
image.CreateOptions = BitmapCreateOptions.None;
WriteableBitmap wb = new WriteableBitmap(image);
wb.SaveJpeg(ms, image.PixelWidth, image.PixelHeight, 0, 100);
return ms.ToArray();
}

WriteableBitmap.SaveJpeg

The line wb.SaveJpeg in the code generates the error: System.Windows.Media.Imaging.WriteableBitmap' does not contain a definition for 'SaveJpeg' and no extension method 'SaveJpeg' accepting a first argument of type 'System.Windows.Media.Imaging.WriteableBitmap' could be found
I've included as references: PresentationCore,PresentaionFramework, System.Windows.Forms,WindowsBase.
BitmapImage image = CaptureImageFromClipBoard();
WriteableBitmap wb = new WriteableBitmap(image);
using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var fs = isf.CreateFile(path + "\\" + filename + ".jpg"))
{
wb.SaveJpeg(fs, wb.PixelWidth, wb.PixelHeight, 10, 100);
}
}
Here's the method CaptureImageFromClipBoard:
static public BitmapImage CaptureImageFromClipBoard()
{
var img = new System.Windows.Controls.Image();
var imgsrc = Clipboard.GetImage();
img.Source = new FormatConvertedBitmap(imgsrc, PixelFormats.Bgr32, null, 0);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
MemoryStream memoryStream = new MemoryStream();
BitmapImage bImg = new BitmapImage();
encoder.Frames.Add(BitmapFrame.Create(imgsrc));
encoder.Save(memoryStream);
bImg.BeginInit();
bImg.StreamSource = new MemoryStream(memoryStream.ToArray());
bImg.EndInit();
memoryStream.Close();
return bImg;
}
I propose to go like this - NOTE: untested, typed from memory and the original post...
static public void SaveCapturedImageFromClipBoard(Stream target)
{
var img = new System.Windows.Controls.Image();
var imgsrc = Clipboard.GetImage();
img.Source = new FormatConvertedBitmap(imgsrc, PixelFormats.Bgr32, null, 0);
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imgsrc));
encoder.Save(target);
}
and
using (var isf = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var fs = isf.CreateFile(path + "\\" + filename + ".jpg"))
{
SaveCapturedImageFromClipBoard(fs);
}
}

Categories