Error: Cannot access a closed file when converting imagefile into bytes - c#

Whenever converting the imagefile into bytes we got an error like
cannot access a closed file
Please help me in order to overcome this
private byte[] ConvertToBytes(HttpPostedFileBase file)
{
byte[] imageBytes = null;
BinaryReader reader = new BinaryReader(file.InputStream);
imageBytes = reader.ReadBytes((int)file.ContentLength);
return imageBytes;
}

Use a BinaryReader object to return a byte array from the stream like:
byte[] fileData = null;
var binaryReader = new BinaryReader(Request.Files[0].InputStream);
fileData = binaryReader.ReadBytes(Request.Files[0].ContentLength);

In case it can help:
try
{
using (var bitmap = new System.Drawing.Bitmap(file.InputStream))
{
using (var memoryStream = new MemoryStream())
{
bitmap.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Jpeg);
return memoryStream.ToArray();
}
}
}
catch (Exception)
{
return null;
}
finally
{
postedFile.InputStream.Position = 0;
}

Related

WCF Compress And Decompress Mehtod Problem Gzip Image Data(Binary) C#

i have two method for compress and decompress base64 image data in sql
server
my decompress method for read data in sql its work but compressing
return wrong data please help me ...
public static Byte[] BinaryCompress(Byte[] InputStream)
{
using (MemoryStream ms = new MemoryStream())
{
using (GZipStream x = new GZipStream(ms, CompressionMode.Compress, true))
{
byte[] inputBytes = (byte[])InputStream;
x.Write(inputBytes, 0, inputBytes.Length);
}
return ms.ToArray();
}
}
public static Byte[] BinaryDecompress(Byte[] InputBinary)
{
byte[] inputBytes = (byte[])InputBinary;
using (MemoryStream msin = new MemoryStream(inputBytes))
{
using (GZipStream x = new GZipStream(msin, CompressionMode.Decompress))
{
using (MemoryStream msout = new MemoryStream())
{
int num = x.ReadByte();
while (num != -1)
{
msout.WriteByte((byte)num);
num = x.ReadByte();
}
return msout.ToArray(); ;
}
}
}
}
Could you please provide more specific exception by using below code?
public static Byte[] BinaryCompress(Byte[] InputStream)
{
try
{
MemoryStream ms = new MemoryStream();
try
{
GZipStream x = new GZipStream(ms, CompressionMode.Compress, true)
byte[] inputBytes = (byte[])InputStream;
x.Write(inputBytes, 0, inputBytes.Length);
}
catch (Exception ex)
{
Console.Write(ex.StackTrace);
}
return ms.ToArray();
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
throw;
}
}

Converting ImageSource to Object Throws Binary stream error

I'm trying to convert/cast an image source to an object. I tried to convert to a byte prior to object.
ImageSource oImageSelectedByUser = (from ii in mySource where ii.PhotoImgStream != null select ii.PhotoImgStream).FirstOrDefault();
var oImageAsByte = await ConvertStreamtoByteAsync(oImageSelectedByUser);
var oImageAsObject = FromByteArray<object>(oImageAsByte);
private static async Task<byte[]> ConvertStreamtoByteAsync(ImageSource imageSource)
{
byte[] buffer = new byte[16 * 1024];
try
{
if (imageSource is FileImageSource)
{
FileImageSource objFileImageSource = (FileImageSource)imageSource;
string strFileName = objFileImageSource.File;
var webClient = new WebClient();
buffer = await webClient.DownloadDataTaskAsync(new Uri(strFileName));
return buffer;
}
}
catch (Exception ex)
{
buffer = null;
}
return buffer;
}
public T FromByteArray<T>(byte[] data)
{
if (data == null)
return default(T);
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
object obj = bf.Deserialize(ms);
return (T)obj;
}
}
When trying to convert to object, the error I get is:
Binary stream '0' does not contain a valid BinaryHeader. Possible
causes are invalid stream or object version change between
serialization and deserialization.
I wanted to ask is there a better way to do this?
Any direction/pointers appreciated.
You could modify the code like following
public T FromByteArray<T>(byte[] data)
{
if (data == null)
return default(T);
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
ms.Seek(0, SeekOrigin.Begin); // /rewinded the stream to the begining.
object obj = bf.Deserialize(ms);
return (T)obj;
}
}

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;
}
}

BitMapImage to byte and reverse

Since two days I try to manage my images in a WPF application but I have errors and errors errors, ...
The image is show in a System.Windows.Control.Image.
For this reason I try to work with variable BitMapImage.
Now I have the error : "Impossible to access close stream" and I can not find a solution.
I have created two function for convert :
public static BitmapImage ConvertToBitMapImage(byte[] bytes)
{
if (bytes == null || bytes.Length == 0) return null;
var image = new BitmapImage();
using (var mem = new MemoryStream(bytes))
{
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;
}
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;
}
In my object I have a property :
public BitmapImage MiniatureApp
{
get
{
if (IMAGES != null)
_MiniatureApp = Tools.BinaryImageConverter.ConvertToBitMapImage(IMAGES.IMAGE);
return _MiniatureApp;
}
set
{
if (this.IMAGES != null)
this.IMAGES.IMAGE = Tools.BinaryImageConverter.ImageToByte((BitmapImage)value);
else
{
IMAGES img = new IMAGES();
img.NOM = "";
img.IMAGE = Tools.BinaryImageConverter.ImageToByte((BitmapImage)value);
this.IMAGES = img;
}
NotifyPropertyChanged();
}
}
And in my main I do this :
FileStream fs = new FileStream(pathImage, FileMode.Open, FileAccess.Read);
byte[] data = new byte[fs.Length];
fs.Read(data, 0, System.Convert.ToInt32(fs.Length));
fs.Close();
VMAppareil.VMApp.CurrentAppareil.MiniatureApp = Tools.BinaryImageConverter.ConvertToBitMapImage(data);
Exist a solution for my problem or exist a best way to do this ?
Gobelet.
You can fix your solution replacing the ImageToByte method with the following (borrowed from https://stackoverflow.com/a/6597746/5574010)
public static byte[] ImageToByte(BitmapImage imageSource)
{
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(imageSource));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
return ms.ToArray();
}
}
Your previous solution did not work because the ConvertToBitMapImage method close the stream that you assign to image.StreamSource as soon as your code exit the unit statement. When you call the ImageToByte method as part of the MiniatureApp setter the StreamSource will be close and you get an error.
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 Encrypt and Decrypt an image in WP8?

I want to Encrypt an image and save in Isolated storage and image decryption while reading.I am able to do normal text data but I didn't find solution for an image.And further I need to encrypt and decrypt PDF/Doc files.
Below is my code
MemoryStream stream = new MemoryStream();
compressedStream.Seek(0, SeekOrigin.Begin);
using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isStore.FileExists(selectedImageName))
using (IsolatedStorageFileStream targetStream = isStore.OpenFile(selectedImageName, FileMode.Create, FileAccess.Write))
{
byte[] readBuffer = new byte[4096];
int bytesRead = -1;
while ((bytesRead = compressedStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
{
targetStream.Write(readBuffer, 0, bytesRead);
}
}
}
To encrypt normal text using below code
public static byte[] Encrypt(string text, string strCacheKey)
{
try
{
return ProtectedData.Protect((Encoding.UTF8.GetBytes(text)), GetToken(strCacheKey));
}
catch (Exception)
{
}
return new byte[0];
}
Thanks in advance.
Finally got answer to encrypt/decrypt Images
Encryption Code:
public static byte[] EncryptImage(byte[] encryptedimage, string strCacheKey)
{
try
{
return ProtectedData.Protect(encryptedimage, GetToken(strCacheKey));
}
catch (Exception)
{
}
return new byte[0];
}
Decryption Code:
public static byte[] DecryptImage(byte[] decryptedimage, string strCacheKey)
{
try
{
return ProtectedData.Unprotect(decryptedimage, GetToken(strCacheKey));
}
catch (Exception)
{
}
return new byte[0];
}
Code for storing in Isolated Storage:
byte[] ibytes = new byte[attachmentStream.Length];
byte[] ImageByte = TextImageEncryptionDecryption.EncryptImage(ibytes, App.cacheKey);
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (IsolatedStorageFileStream targetStream = new IsolatedStorageFileStream(selectedImageName,
FileMode.Create, FileAccess.Write, store))
{
targetStream.Write(ImageByte, 0, ImageByte.Length);
}
Code to Read image from ISO:
using (var stream = iso.OpenFile(name, FileMode.Open, FileAccess.Read))
{
byte[] ImgStr = ReadFully(stream);
byte[] Img = TextImageEncryptionDecryption.DecryptImage(ImgStr, App.cacheKey);
Stream Imagestream = new MemoryStream(Img);
image.SetSource(Imagestream);
imgAttach = image;
}
return imgAttach;
}
Cheers !!

Categories