Parameter is not valid when i retrieve Image - c#

string nama = dgGambar1.Rows[e.RowIndex].Cells["nama_gambar"].FormattedValue.ToString();
btnTambahDataBarang.Enabled = false;
koneksi.Open();
MySqlCommand command = new MySqlCommand("SELECT * FROM and_bwi_gambar WHERE nama_gambar = '" + nama + "'", koneksi);
MySqlDataReader rd;
rd = command.ExecuteReader();
while (rd.Read())
{
txtGambar1.Text = rd.GetValue(2).ToString();
byte[] img = (byte[])rd.GetValue(3);
MemoryStream ms = new MemoryStream(img);
pbGambar1.Image = Image.FromStream(ms);
}
koneksi.Close();
when i retrieve an image whose size is more than 250kb, it always get an error 'parameter argument invalid'

There could be 2 options to solve this:
using image converter:
byte[] buffer = (byte[])rd.GetValue(3);
using(var memStream = new MemoryStream(buffer))
{
var ic = new System.Drawing.ImageConverter();
pbGambar1.Image = (System.Drawing.Image)ic.ConvertFrom(stream.ReadAllBytes());
}
or try to load up binary data into memory stream first:
byte[] buffer = (byte[])rd.GetValue(3);
using(var memStream = new MemoryStream(buffer))
{
memStream.Position = 0;
pbGambar1.Image = System.Drawing.Image.FromStream(memStream, false);
}
}

Related

How can I get a Bitmap image from SQL Server and show it in a PictureBox?

When I get a Bitmap image from SQL Server DB to display it in a PictureBox, I get an exception:
Parameter is not valid error
Here's my code:
public void FillHotMenu(int key, string connection, string logdir)
{
try
{
SqlConnection conn = new SqlConnection(connectionstr);
conn.Open();
SqlCommand cmd = new SqlCommand("Pm_R_GetHotMenus", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#keyid", key);
SqlDataReader read = cmd.ExecuteReader();
flowLayoutPanel1.Controls.Clear();
while (read.Read())
{
byte[] b = (byte[])(read["KeyBitmap"]);
if (b.Length > 1)
{
PictureBox pic = new PictureBox();
pic.Size = new Size(flowLayoutPanel1.Width / 4, flowLayoutPanel1.Height / 4);
string s = read["KeyBitmap"].ToString();
using (MemoryStream ms = new MemoryStream(b))
{
Bitmap image = new Bitmap(ms); // *** I'm getting error here
pic.Image = image;
}
pic.SizeMode = PictureBoxSizeMode.StretchImage;
flowLayoutPanel1.Controls.Add(pic);
}
else if (read["KeyTextValue"].ToString() != "")
{
textvalue = "";
PictureBox pic = new PictureBox();
pic.Size = new Size(flowLayoutPanel1.Width / 4, flowLayoutPanel1.Height / 4);
textvalue = read["KeyTextValue"].ToString();
pic.Paint += new PaintEventHandler(pictureBox1_Paint);
flowLayoutPanel1.Controls.Add(pic);
}
}
conn.Close();
}
catch (Exception ex)
{
string logstr = ex.InnerException == null ? "" : ex.InnerException.Message;
log.append("ERROR:" + ex.Message + "-->" + logstr, logdirectory);
MessageBox.Show(ex.Message);
Environment.Exit(0);
}
}
How can I solve this problem?
Edit:
I've tried this code with no exceptions but nothing is shown in the PictureBox:
var ms = new MemoryStream(b);
ms.Seek(0, SeekOrigin.Begin);
ms.Position = 0;
byte[] imagebytes = ms.ToArray();
Bitmap bitmap = new Bitmap(pic.Width, pic.Height);
bitmap.Save(ms, ImageFormat.Png);
pic.Image = Image.FromStream(ms);
pic.SizeMode = PictureBoxSizeMode.StretchImage;

Not able to get more then one results with images in WPF datagrid from Mysql Database in C#

With this code i am able to get one image from Mysql database in C# in WPF. But i have a table in database that contaon all countries's names and their
flag etc. When i query to select many or all countries folling error occur
"Cannot set the initializing state more than once" at this line "bi.BeginInit()".
Thanks in advance.
string co = null;
string na = null;
string le = null;
string gn = null;
string A = "pak";
BitmapImage bi = new BitmapImage();
try
{
MySqlCommand cmd = new MySqlCommand("Select Code,Name,LifeExpectancy,GNP,flg from country where Name REGEXP '" + A + "'", connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
co = dataReader["Code"].ToString();
na = dataReader["Name"].ToString();
le = dataReader["LifeExpectancy"].ToString();
gn = dataReader["GNP"].ToString();
Byte[] bindata = (Byte[])dataReader["flg"];
MemoryStream strm = new MemoryStream();
strm.Write(bindata, 0, bindata.Length);
strm.Position = 0;
System.Drawing.Image img = System.Drawing.Image.FromStream(strm);
bi.BeginInit();
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
dt.Rows.Add(co, na, le, gn, bi);
dataGridCustomers.ItemsSource = dt.DefaultView;
}
}
catch (MySqlException ex)
{
MessageBox.Show(ex.ToString());
}
The reason for this is because you are creating the BitmapImage outside of the loop. So Once you get in the loop it keeps trying to set the initializing state on the same image. As your error states you can't do this. What you need to do is create a new BitmapImage on each iteration. Which can be accomplished by moving the line
BitmapImage bi = new BitmapImage();
To the inside of the loop. Unless there is a specific reason you are initializing it where you are.
string co = null;
string na = null;
string le = null;
string gn = null;
string A = "pak";
try
{
MySqlCommand cmd = new MySqlCommand("Select Code,Name,LifeExpectancy,GNP,flg from country where Name REGEXP '" + A + "'", connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
BitmapImage bi = new BitmapImage();
co = dataReader["Code"].ToString();
na = dataReader["Name"].ToString();
le = dataReader["LifeExpectancy"].ToString();
gn = dataReader["GNP"].ToString();
Byte[] bindata = (Byte[])dataReader["flg"];
MemoryStream strm = new MemoryStream();
strm.Write(bindata, 0, bindata.Length);
strm.Position = 0;
System.Drawing.Image img = System.Drawing.Image.FromStream(strm);
bi.BeginInit();
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
dt.Rows.Add(co, na, le, gn, bi);
dataGridCustomers.ItemsSource = dt.DefaultView;
}
}
catch (MySqlException ex)
{
MessageBox.Show(ex.ToString());
}
EDIT: In the code above, the System.Drawing.Image is entirely redundant. You should directly create the BitmapImage from the byte array like this:
var bindata = (byte[])dataReader["flg"];
var bi = new BitmapImage();
using (var stream = new MemoryStream(bindata))
{
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = stream;
bi.EndInit();
}

How to retrieve image from database of image datatype to the PhotoBox in c#

The code below is my photo selecting selector (the other button I have in my project is just sending the picArray to the table in the column of image datatype):
private void FileSelectorButton_Click(object sender, EventArgs e)
{
OpenFileDialog ImageSelectorWindow = new OpenFileDialog();
ImageSelectorWindow.Filter = "JPG |*.jpg|PNG |*.png|Bitmap |*.bmp";
ImageSelectorWindow.Title = "Choose an Image";
if (ImageSelectorWindow.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
fileName = ImageSelectorWindow.FileName;
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
picArray = new byte[fs.Length];
fs.Read(picArray, 0, Convert.ToInt32(fs.Length));
fs.Close();
}
TBFilePath.Text = fileName;
}
Below is my image retrieval code:
SqlCommand cmd2 = new SqlCommand("SELECT avatar FROM Members WHERE Id = '" + value + "'", con);
SqlDataReader dr = cmd2.ExecuteReader();
MemoryStream ms = new MemoryStream((byte[])dr[0]);
PBMemberImage.BackgroundImage = new Bitmap(ms);
This is giving me the following exception:
Can someone help me figure out why?
Retrieve Images from sql server database
Take a look at that and try the code below for retrieving your image. Let me know if that works or not.
byte[] img = (byte[])cmd2.ExecuteScalar();
MemoryStream ms = new MemoryStream();
ms.Write(img, 0, img.Length);
PBMemberImage.BackgroundImage = new Bitmap(ms);

No imaging component suitable to complete this operation was found.wpf c# [duplicate]

This question already has an answer here:
No imaging component suitable to complete the operation was found WPF vb.net
(1 answer)
Closed 4 years ago.
I'm trying to load image from my .mdb database in WPF. I'm using this code :
public void loadimg()
{
con.Open();
OleDbCommand cmd = new OleDbCommand("Select * from recents", con);
DataTable table = new DataTable;
OleDbDataAdapter adap = new OleDbDataAdapter(cmd);
adap.Fill(table);
if (table.Rows.Count <= 0)
{
MsgBox("nooo");
}
else
{
MemoryStream stream = new MemoryStream();
StreamWriter stm;
BinaryWriter writer = new BinaryWriter(stream);
int bufferSize = 100;
byte[] outByte = new byte[bufferSize + 1];
long retval;
long startIndex = 0;
string pubID = "";
OleDbDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);
reader.Read();
while (reader.Read())
{
startIndex = 0;
retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
while (retval == bufferSize)
{
writer.Write(outByte);
writer.Flush();
startIndex += bufferSize;
retval = reader.GetBytes(1, startIndex, outByte, 0, bufferSize);
}
writer.Write(outByte, 0, (int)retval - 1);
writer.Flush();
}
reader.Close();
con.Close();
stream.Position = 0;
stream.Seek(0, SeekOrigin.Begin);
System.Drawing.Image _Image = System.Drawing.Image.FromStream(stream);
image1.Source = System.Windows.Media.Imaging.BitmapFrame.Create(stream);
}
}
The code above returns an error :
No imaging component suitable to complete this operation was found.
I spent hours trying to figure out how to fix it.Any help would be highly appreciated.
Update
In the comments, i was asked if i inserted the data properly..Well,here's the code i used to insert the data :
public void adddata()
{
con.Open();
OleDbCommand cmd = new OleDbCommand("Insert into recents(Pic)values(#pic)", con);
byte[] data;
System.Drawing.Image myimage = System.Drawing.Image.FromFile("E:\\19686468_1419770068104721_1127495277_o.png");
using (MemoryStream ms = new MemoryStream())
{
myimage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
data = ms.ToArray();
}
cmd.Parameters.AddWithValue("#pic", data);
cmd.ExecuteNonQuery();
con.Close();
}
Please help me out!
Fixed it...For anyone who faces this error in future :
Make sure you're inserting the data in the proper way(sometimes corrupted data in the db causes such errors)
2 . You don't need to do some heavy coding to convert the image to byte!
Finally,let's code :
public void loadimg()
{
con.Open();
OleDbCommand cmd = new OleDbCommand("Select * from recents", con);
OleDbDataReader _dr;
_dr = cmd.ExecuteReader;
byte[] _photo;
while (_dr.Read())
{
try
{
_photo = (byte[])_dr(1);
BitmapImage bi = new BitmapImage();
using (MemoryStream strm = new MemoryStream(_photo))
{
bi.BeginInit();
bi.CacheOption = BitmapCacheOption.OnLoad;
bi.StreamSource = strm;
bi.EndInit();
}
image1.Source = bi;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

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

Categories