I got the new image successfully, but I can't get the original image, the image was cropped.
Here is the code I tried:
private byte[] ConvertToCCITT4(byte[] input)
{
MemoryStream memoryStream1 = new MemoryStream(input);
RasterCodecs.CodecsPath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;
RasterCodecs rasterCodecs = new RasterCodecs();
using (IRasterImage irasterImage = rasterCodecs.Load((Stream)memoryStream1))
{
MemoryStream memoryStream2 = new MemoryStream();
rasterCodecs.Save(irasterImage, (Stream)memoryStream2, (RasterImageFormat)29, 1);
return memoryStream2.ToArray();
}
}
Related
The last line of the following code gives the error "Parameter is not valid", when the original image is an SVG:
var imageBytes = Convert.FromBase64String(imageBase64String);
var memStream = new MemoryStream(imageBytes);
//memStream.Seek(0, SeekOrigin.Begin);
var imageObject = new Bitmap(memStream);
Help please. Thanks.
EDIT: The image for example I am using is the image of the first formula in the following page right under the Theoremsection:
https://en.wikipedia.org/wiki/Green%27s_theorem
Can you try with 'using' for memorystream to handle garbage collection by itself?
var imageBytes = Convert.FromBase64String(imageBase64String);
Bitmap m = ByteToBitmap(imageBytes);
public static Bitmap ByteToBitmap(byte[] imageByte)
{
using (MemoryStream mStream = new MemoryStream())
{
mStream.Write(imageByte, 0, imageByte.Length); // this will stream dataand handle image length by itself
mStream.Seek(0, SeekOrigin.Begin);
Bitmap bm = new Bitmap(mStream);
return bm;
}
}
For SVG,
public static Bitmap ByteToBitmap(byte[] imageByte)
{
using (MemoryStream mStream = new MemoryStream(imageByte))
{
var s= SvgDocument.Open(mStream);
var bm= svgDocument.Draw();
return bm;
}
}
so .. am creating a Simple Desktop Viewer application.
but i keep getting this System.outOfMmemoryException when ever i try to de-serialize sent images through the stream.
the sending code :
private Image getScreen() {
Rectangle bound = Screen.PrimaryScreen.Bounds;
Bitmap ScreenShot = new Bitmap(bound.Width,bound.Height,PixelFormat.Format32bppArgb );
Graphics image = Graphics.FromImage(ScreenShot);
image.CopyFromScreen(bound.X,bound.Y,0,0,bound.Size,CopyPixelOperation.SourceCopy);
return ScreenShot;
}
private void SendImage() {
BinaryFormatter binFormatter = new BinaryFormatter();
binFormatter.Serialize(stream, getScreen());
}
note that the images are sent using a timer that calls the SendImage() once it's started
this is my Recieving Code :
BinaryFormatter binFormatter = new BinaryFormatter();
Image img = (Image)binFormatter.Deserialize(stream);
picturebox1.Image=img;
so .. whats Wrong?
Most likely this caused by a wrong usage of Stream. The code below is working fine:
private Image getScreen() {
Rectangle bound = Screen.PrimaryScreen.Bounds;
Bitmap ScreenShot = new Bitmap(bound.Width,bound.Height,PixelFormat.Format32bppArgb );
Graphics image = Graphics.FromImage(ScreenShot);
image.CopyFromScreen(bound.X,bound.Y,0,0,bound.Size,CopyPixelOperation.SourceCopy);
return ScreenShot;
}
private void SendImage(Stream stream) {
BinaryFormatter binFormatter = new BinaryFormatter();
binFormatter.Serialize(stream, getScreen());
}
void Main()
{
byte[] bytes = null;
using (var ms = new MemoryStream()) {
SendImage(ms);
bytes = ms.ToArray();
}
var receivedStream = new MemoryStream(bytes);
BinaryFormatter binFormatter = new BinaryFormatter();
Image img = (Image)binFormatter.Deserialize(receivedStream);
img.Save("c:\\temp\\test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}
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;
}
}
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;
}
}
MemoryStream ms = new MemoryStream(fileData.FileData1.ToArray());
Image showImage = null;
using (System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms))
{
returnImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
MemoryStream msSave = new MemoryStream();
showImage = FixedSize(returnImage, returnImage.Width, returnImage.Height);
int hei = showImage.Height;
int wid = showImage.Width;
showImage.Save(msSave, imageFormat);
context.Response.BinaryWrite(msSave.ToArray());
}
It was all working fine till sometime ago :/