i am trying to save images like bmp,jpg,gif & png into sql server database. but not able to save all the formats into database. Only png image is getting saved into database. if trying to save jpeg, .bmp & .gif images, it's showing error "A generic error occured in GDI+". What is the problem?
private void InitializeOpenFileDialog()
{
try
{
this.openFileDialog1 = new OpenFileDialog();
// Set the file dialog to filter for graphics files.
this.openFileDialog1.Filter = "Images (*.BMP;*.JPG;*.GIF;*.PNG)|*.BMP;*.JPG;*.GIF;*.PNG|" + "All files (*.*)|*.*";
//"image files|*.jpg;*.png;*.gif;*.bmp;.*;";
// Allow the user to select multiple images.
this.openFileDialog1.Multiselect = true;
this.openFileDialog1.Title = "My Image Browser";
}
catch(Exception es){
MessageBox.Show(es.Message);
}
}
//load picture
private void button1_Click(object sender, EventArgs e)
{
openFileDialog1.ShowDialog();
}
private void button2_Click(object sender, EventArgs e)
{
try
{
MemoryStream ms1 = new MemoryStream();
pictureBox2.Image.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg);
// byte[] img_arr1 = ms1.ToArray();
byte[] img_arr1 = new byte[ms1.Length];
ms1.Read(img_arr1, 0, img_arr1.Length);
SqlConnection con = new SqlConnection(#"data source=xdfgh\ALEXDAVE;database=x1234;UID=sa;password=x67890");
con.Open();
SqlCommand cmd = new SqlCommand("insert into myTable(enrolmentno,aadhaarno,name,fname,address,dob,gender,picimage)values(#a,#b,#c,#d,#e,#f,#g,#h)", con);
cmd.Parameters.AddWithValue("#a", enrolmentno_txt.Text);
cmd.Parameters.AddWithValue("#b", aadhaarno_txt.Text);
cmd.Parameters.AddWithValue("#c", name_txt.Text);
cmd.Parameters.AddWithValue("#d", fname_txt.Text);
cmd.Parameters.AddWithValue("#e", address_txt.Text);
cmd.Parameters.AddWithValue("#f", dateTimePicker1.Text);
cmd.Parameters.AddWithValue("#g", gender);
cmd.Parameters.AddWithValue("#h", img_arr1);
int result = cmd.ExecuteNonQuery();
if (result > 0)
MessageBox.Show("Data inserted successfully");
else
MessageBox.Show("Data is not inserted in database");
con.Close();
}
catch(Exception es){
MessageBox.Show(es.Message);
}
}
}
private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
{
this.Activate();
string[] files = openFileDialog1.FileNames;
try
{
foreach (string file in files)
{
FileInfo fileInfo = new FileInfo(file);
FileStream fileStream = fileInfo.OpenRead();
pictureBox2.Image = Image.FromStream(fileStream);
Application.DoEvents();
fileStream.Close();
}
}
//es
catch (Exception)
{
MessageBox.Show("please select only image files.");
}
}
Are you sure the the image is valid?
What line are you getting the error on?
Like the error indicates, it's a GDI error, and not a SQL Error.
You can remove the need for GDI by replacing the following lines of code
MemoryStream ms1 = new MemoryStream();
pictureBox2.Image.Save(ms1, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] img_arr1 = new byte[ms1.Length];
ms1.Read(img_arr1, 0, img_arr1.Length);
with this
byte[] img_arr1 = System.IO.File.ReadAllBytes(fileName);
where fileName is the file that was selected
Related
Code query database:
I can't save the PDF files to my database, I have a serious problem in the database storage area.
public void ADDWORK(String MAW, string NAMEW, string IDUSER, bool Image,string room, byte[] document,string content,bool donework)
{
String strSql = string.Format("INSERT INTO WORK(IDWORD,NAMEWORk,IDUSER,IMAGES,IDROOM,DOCUMENTS,CONTENT,DONEWORK)VALUES('{0}',N'{1}',N'{2}','{3}',N'{4}',N'{5}',N'{6}',N'{7}')"
, MAW, NAMEW, IDUSER, Image,room,document,content,donework);
db.ExecuteNonQuery(strSql);
}
Code call function:
byte[] pdf;
public void UploadFlie(string file)
{
FileStream fileStream = File.OpenRead(file);
byte[] contents = new byte[fileStream.Length];
fileStream.Read(contents, 0, (int)fileStream.Length);
fileStream.Close();
pdf = contents;
}
private void button1_Click(object sender, EventArgs e)
{
UploadFlie(filename);
dg.ADDWORK(idword, textBox1.Text,"1", false,"ROOM1", pdf, richTextBox1.Text, false);
MessageBox.Show("Done!");
}
here is my example how to get any file and save it on database.
I use two diffrent methods
Saving byte array.
Saving Stream
First you need to create column varbinary(MAX) in my case I called it - PdfFile
and PdfExtn column to save the type of the file As varchar(10) (You can use 4).
Saving byte array:
private void btnGetFile_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
if (result == DialogResult.OK) // Test result.
{
string file = openFileDialog1.FileName;
string extn = new FileInfo(file).Extension;
try
{
byte[] fileBytes = File.ReadAllBytes(file);
string cmd = "INSERT INTO Employee(Id,FirstName,LastName,Email,Password,PdfFile,FileExtn) VALUES (#Id,#FirstName,#LastName,#Email,#Password,#PdfFile,#FileExtn)";
List<SqlParameter> l = new List<SqlParameter>();
l.Add(new SqlParameter("#Id", "101"));
l.Add(new SqlParameter("#FirstName", "Aviv"));
l.Add(new SqlParameter("#LastName", "Halevy"));
l.Add(new SqlParameter("#Email", "Assadsa#gmail.com"));
l.Add(new SqlParameter("#Password", "123456"));
SqlParameter sp = new SqlParameter("#PdfFile", SqlDbType.VarBinary, -1);
sp.Value = fileBytes;
l.Add(sp);
l.Add(new SqlParameter("#FileExtn", extn));
if (DAL.Database.ParametersCommand(cmd, l) > 0)
textBox1.Text = "SUCCESS! Save with byte array";
}
catch (IOException ex)
{
}
}
}
Write the file from bytes:
private void btnReadFromDb_Click(object sender, EventArgs e)
{
string cmd = "SELECT * FROM Employee WHERE Id = '101'";
string path = "YOUR_PATH\\Test";
DataTable dt = DAL.Database.GetDataTable(cmd);
if (dt != null && dt.Rows.Count > 0)
{
Byte[] file = (Byte[])dt.Rows[0]["PdfFile"];
string extn = dt.Rows[0]["FileExtn"].ToString();
path = Path.Combine(path, "Test321"+extn);
File.WriteAllBytes(path, file);
Process.Start(path);
}
}
And the result:
Using Stream
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog1 = new OpenFileDialog();
DialogResult result = openFileDialog1.ShowDialog(); // Show the dialog.
if (result == DialogResult.OK) // Test result.
{
string file = openFileDialog1.FileName;
using (Stream stream = File.OpenRead(file))
{
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, buffer.Length);
string extn = new FileInfo(file).Extension;
string cmd = "INSERT INTO Employee(Id,FirstName,LastName,Email,Password,PdfFile,FileExtn) VALUES (#Id,#FirstName,#LastName,#Email,#Password,#PdfFile,#FileExtn)";
List<SqlParameter> l = new List<SqlParameter>();
l.Add(new SqlParameter("#Id", "102"));
l.Add(new SqlParameter("#FirstName", "Aviv"));
l.Add(new SqlParameter("#LastName", "Halevy"));
l.Add(new SqlParameter("#Email", "Assadsa#gmail.com"));
l.Add(new SqlParameter("#Password", "123456"));
l.Add(new SqlParameter("#PdfFile", buffer));
l.Add(new SqlParameter("#FileExtn", extn));
if (DAL.Database.ParametersCommand(cmd, l) > 0)
textBox1.Text = "SUCCESS! Save with Stream";
}
}
}
Write the file from stream:
private void button2_Click(object sender, EventArgs e)
{
string cmd = "SELECT * FROM Employee WHERE ID = '102'";
string path = "YOUR_PATH\\Test";
DataTable dt = DAL.Database.GetDataTable(cmd);
if (dt != null && dt.Rows.Count > 0)
{
Byte[] file = (Byte[])dt.Rows[0]["PdfFile"];
string extn = dt.Rows[0]["FileExtn"].ToString();
path = Path.Combine(path, "Test123"+extn);
File.WriteAllBytes(path, file);
Process.Start(path);
}
}
And the result:
Note:
In my examples the DAL project has a static methods that runs my sql commands.
i have a win form that let user enter 2 textboxes that are obligatory after selecting a combobox, and a button to add image if he wants and another button where the insert to sql happens
My upload image code:
private void BUpload_Click(object sender, EventArgs e)
{
if (CmbImo.SelectedIndex != -1) {
OpenFileDialog open = new OpenFileDialog();
open.Filter = "Image Files(*.jpeg;*.bmp;*.png;*.jpg)|*.jpeg;*.bmp;*.png;*.jpg";
if (open.ShowDialog() == DialogResult.OK)
{
pictureBox1.Text = open.FileName;
pictureBox1.Image = Image.FromFile(open.FileName);
}
else
{
label2.ForeColor = Color.Red;
label2.Text = "please Upload an Image";
}
}
else
{
MessageBox.Show("Please Do Select an Imo Vessel !!");
}
}
and this is the procedure that i have in the last add button that inserts into sql
public void SaveATLast()
{
string image = pictureBox1.Text;
if (CmbImo.SelectedIndex != -1 && textBox1.Text!="" && textBox3.Text != "") {
cnx.Open();
// string image = pictureBox1.Text;
Bitmap bmp = new Bitmap(image);
FileStream fs = new FileStream(image, FileMode.Open, FileAccess.Read);
byte[] bimage = new byte[fs.Length];
fs.Read(bimage, 0, Convert.ToInt32(fs.Length));
fs.Close();
SqlCommand cmd = new SqlCommand("insert into Bay2(VessImo,CatwalkHeight,BayName,ImageBay) values (#VessImo,#CatwalkHeight,#BayName,#imgdata)", cnx);
cmd.Parameters.AddWithValue("#VessImo", SqlDbType.Int).Value = CmbImo.SelectedItem.ToString();
cmd.Parameters.AddWithValue("#CatwalkHeight", SqlDbType.Int).Value = int.Parse(textBox3.Text);
cmd.Parameters.AddWithValue("#BayName", SqlDbType.Int).Value = int.Parse(textBox1.Text);
cmd.Parameters.AddWithValue("#imgdata", SqlDbType.Image).Value = bimage;
//cmd.Parameters.AddWithValue("#BayName", SqlDbType.Int).Value = comboBox1.SelectedItem.ToString();
cmd.ExecuteNonQuery();
cnx.Close();
//this.Close();
textBox1.Clear();
textBox3.Clear();
pictureBox1.Image = null;
}else
{
MessageBox.Show("please Do Fill all Textboxes !!");
}
}
when getting to the point where i dont wanna add a picture but instead just filling the two txtboxes needed it give me
System.ArgumentException: 'The path does not have a conforming form.'
UPDATE:
Just to be clear when i actually click upload image and fill the 2 textboxes it actually does get inserted in database , what i want is it doesnt matter if picture is uploaded or not meaning if picturebox is empty or not
Note that in sql the image column is NOT SET TO "NOT NULL"
You are using the wrong property to get the image path. The correct property is ImageLocation.
string image = pictureBox1.ImageLocation;
If your image field in database is null then you need to set the value to DBNull.
cmd.Parameters.AddWithValue("#imgdata", SqlDbType.Image).Value = (bimage == null) ? DBNull.Value : bimage;
I tried a code from the internet and it's working fine. It can upload any kind of file to a SQL database and can retrieve it from SQL database.
But my problem is how can i open any kind of file from SQL database without saving it in the computer.I want to open stored file without saving. like if it is a excel file i want to open it in excel. And then user can save it or not. thank you Here is my code..
private void button6_Click(object sender, EventArgs e)
{
SaveAttachment(sfdMain, gridViewMain);
FillDataGrid(gridViewMain, strQuery_AllAttachments); // refresh grid
}
private void SaveAttachment(SaveFileDialog objSfd, DataGridView objGrid)
{
string strId = objGrid.SelectedRows[0].Cells["ID"].Value.ToString();
if (!string.IsNullOrEmpty(strId))
{
SqlCommand sqlCmd = new SqlCommand(strQuery_GetAttachmentById, objConn);
sqlCmd.Parameters.AddWithValue("#attachId", strId);
SqlDataAdapter objAdapter = new SqlDataAdapter(sqlCmd);
DataTable objTable = new DataTable();
DataRow objRow;
objAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
SqlCommandBuilder sqlCmdBuilder = new SqlCommandBuilder(objAdapter);
objAdapter.Fill(objTable);
objRow = objTable.Rows[0];
byte[] objData;
objData = (byte[])objRow["attachment"];
if (objSfd.ShowDialog() != DialogResult.Cancel)
{
string strFileToSave = objSfd.FileName;
FileStream objFileStream =
new FileStream(strFileToSave, FileMode.Create, FileAccess.Read);
objFileStream.Write(objData, 0, objData.Length);
objFileStream.Close();
}
}
}
private void button5_Click(object sender, EventArgs e)
{
if (ofdMain.ShowDialog() != DialogResult.Cancel)
{
CreateAttachment(ofdMain.FileName); //upload the attachment
}
FillDataGrid(gridViewMain, strQuery_AllAttachments); //refresh grid
}
private void CreateAttachment(string strFile)
{
SqlDataAdapter objAdapter =
new SqlDataAdapter(strQuery_AllAttachments_AllFields, objConn);
objAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
SqlCommandBuilder objCmdBuilder = new SqlCommandBuilder(objAdapter);
DataTable objTable = new DataTable();
FileStream objFileStream =
new FileStream(strFile, FileMode.Open, FileAccess.Read);
int intLength = Convert.ToInt32(objFileStream.Length);
byte[] objData;
objData = new byte[intLength];
DataRow objRow;
string[] strPath = strFile.Split(Convert.ToChar(#"\"));
objAdapter.Fill(objTable);
objFileStream.Read(objData, 0, intLength);
objFileStream.Close();
objRow = objTable.NewRow();
//clip the full path - we just want last part!
objRow["fileName"] = strPath[strPath.Length - 1];
objRow["fileSize"] = intLength / 1024; // KB instead of bytes
objRow["attachment"] = objData; //our file
objTable.Rows.Add(objRow); //add our new record
objAdapter.Update(objTable);
}
Just as a warning, you may be going down the wrong route. Putting files in your database is rarely the way to go. It can cause you problems, not just in size but speed and load on your database.
Instead, why don't you investigate one of the many options of cloud storage? Azure for example has private blob storage that you can use, and it is built for this purpose. It also has an emulator so you can test it locally.
This Is the code for Adding the new Item...
private KrystalCafeDatabaseEntities kce = new KrystalCafeDatabaseEntities();
private Byte[] byteBLOBData;
public AddItem()
{
InitializeComponent();
cmbCategory.DataSource = kce.tblItemTypes;
cmbCategory.DisplayMember = "Name";
cmbCategory.ValueMember = "ItemType";
}
private void btnUpload_Click(object sender, EventArgs e)
{
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
{
FileStream fsBLOBFile = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
byteBLOBData = new Byte[fsBLOBFile.Length];
fsBLOBFile.Read(byteBLOBData, 0, byteBLOBData.Length);
fsBLOBFile.Close();
MemoryStream stmBLOBData = new MemoryStream(byteBLOBData);
pbImage.Image = Image.FromStream(stmBLOBData);
}
}
private void btnSave_Click(object sender, EventArgs e)
{
tblItem Item = new tblItem();
Item.Name = txtName.Text;
Item.Price = decimal.Parse(txtPrice.Text);
Item.Image = byteBLOBData;
Item.ItemType = (int)cmbCategory.SelectedValue;
kce.AddTotblItems(Item);
kce.SaveChanges();
MessageBox.Show("Record Saved! :D");
}
}
}
The program runs normally but the data will only be stored for awhile, then If i either closed my program or edit my code the data I just added will be lost.
One likely error is that KrystalCafeDatabaseEntities opens a transaction and you need to commit that transaction after calling SaveChanges.
I am selecting file from openfiledialoge and displaying it in picturebox and its name in textbox when I click on delete button I am getting exception The process cannot access the file because it is being used by another process.
I searched a lot for this exception to get resolved but i didn't fine any of them working, when i tried closing file with imagename which is in textbox i.e the file i am displaying in picturebox ; using IsFileLocked method,this closes and deletes all files of particular directory path ,but how can I delete the only file shown in picturebox,where I am going wrong
public partial class RemoveAds : Form
{
OpenFileDialog ofd = null;
string path = #"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\"; // this is the path that you are checking.
public RemoveAds()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(path))
{
ofd = new OpenFileDialog();
ofd.InitialDirectory = path;
DialogResult dr = new DialogResult();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName);
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
ofd.RestoreDirectory = true;
}
}
else
{
return;
}
}
private void button2_Click(object sender, EventArgs e)
{
//Image img = new Bitmap(ofd.FileName);
string imgName = ofd.SafeFileName;
if (Directory.Exists(path))
{
var directory = new DirectoryInfo(path);
foreach (FileInfo file in directory.GetFiles())
{ if(!IsFileLocked(file))
file.Delete();
}
}
}
public static Boolean IsFileLocked(FileInfo path)
{
FileStream stream = null;
try
{ //Don't change FileAccess to ReadWrite,
//because if a file is in readOnly, it fails.
stream = path.Open ( FileMode.Open, FileAccess.Read, FileShare.None );
}
catch (IOException)
{ //the file is unavailable because it is:
//still being written to or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
}
Thanks in advance for any help
The (previously) accepted answer to this question is very poor practice. If you read the documentation on System.Drawing.Bitmap, in particular for the overload that creates a bitmap from a file, you will find :
The file remains locked until the Bitmap is disposed.
in your code you create the bitmap and store it in a local variable but you never dispose of it when you are done. This means your image object has gone out of scope but has not released its lock on the image file you are trying to delete. For all objects that implement IDisposable (like Bitmap) you must dispose of them yourself. See this question for example (or search for others - this is a very important concept!).
To correct the problem properly you simply need to dispose of the image when you are done with it :
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName); // create the bitmap
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
ofd.RestoreDirectory = true;
img.Dispose(); // dispose the bitmap object
}
Please do not take the advice in the answer below - you should nearly never need to call GC.Collect and if you need to do it to make things work it should be a very strong signal that you are doing something else wrong.
Also, if you only want to delete the one file (the bitmap you have displayed) your deletion code is wrong and will delete every file in the directory as well (this is just repeating Adel's point). Further, rather than keep a global OpenFileDialog object alive simply to store the file name, I would suggest getting rid of that and saving just the file info :
FileInfo imageFileinfo; //add this
//OpenFileDialog ofd = null; Get rid of this
private void button1_Click(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(path))
{
OpenFileDialog ofd = new OpenFileDialog(); //make ofd local
ofd.InitialDirectory = path;
DialogResult dr = new DialogResult();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName);
imageFileinfo = new FileInfo(ofd.FileName); // save the file name
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
ofd.RestoreDirectory = true;
img.Dispose();
}
ofd.Dispose(); //don't forget to dispose it!
}
else
{
return;
}
}
Then in your second button handler you can just delete the one file you are interested in.
private void button2_Click(object sender, EventArgs e)
{
if (!IsFileLocked(imageFileinfo))
{
imageFileinfo.Delete();
}
}
I had the same problem : I loaded a file in a PictureBox and when trying to delete it I got the same exception.
This occurred only when the image was displayed.
I tried them all :
picSelectedPicture.Image.Dispose();
picSelectedPicture.Image = null;
picSelectedPicture.ImageLocation = null;
and still got the same exception.
Then I found this on CodeProject : [c#] delete image which is opened in picturebox.
Instead of using PictureBox.Load() it creates an Image from the file and sets it as PictureBox.Image:
...
// Create image from file and display it in the PictureBox
Image image = GetCopyImage(imagePath);
picSelectedPicture.Image = image;
...
private Image GetCopyImage(string path) {
using (Image image = Image.FromFile(path)) {
Bitmap bitmap = new Bitmap(image);
return bitmap;
}
}
No more exceptions when I delete the file.
IMHO, this is the most suitable solution.
EDIT
I forgot to mention that you can safely delete the file immediately after display :
...
// Create image from file and display it in the PictureBox
Image image = GetCopyImage(imagePath);
picSelectedPicture.Image = image;
System.IO.File.Delete(imagePath);
...
use this code
string imgName = ofd.SafeFileName;
if (Directory.Exists(path))
{
var directory = new DirectoryInfo(path);
foreach (FileInfo file in directory.GetFiles())
{
GC.Collect();
GC.WaitForPendingFinalizers();
file.Delete();
}
}
Your button2_Click event handler is cycling through all the files inside your directory & doing the deletes.
You need to change your code like the following:
public partial class RemoveAds : Form
{
OpenFileDialog ofd = null;
string path = #"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\"; // this is the path that you are checking.
string fullFilePath;
public RemoveAds()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (System.IO.Directory.Exists(path))
{
ofd = new OpenFileDialog();
ofd.InitialDirectory = path;
DialogResult dr = new DialogResult();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Image img = new Bitmap(ofd.FileName);
string imgName = ofd.SafeFileName;
txtImageName.Text = imgName;
pictureBox1.Image = img.GetThumbnailImage(350, 350, null, new IntPtr());
fullFilePath = ofd.FilePath;
ofd.RestoreDirectory = true;
}
}
else
{
return;
}
}
private void button2_Click(object sender, EventArgs e)
{
FileInfo file = new FileInfo(fullFilePath);
if(!IsFileLocked(file))
file.Delete();
}
}
public static Boolean IsFileLocked(FileInfo path)
{
FileStream stream = null;
try
{ //Don't change FileAccess to ReadWrite,
//because if a file is in readOnly, it fails.
stream = path.Open ( FileMode.Open, FileAccess.Read, FileShare.None );
}
catch (IOException)
{ //the file is unavailable because it is:
//still being written to or being processed by another thread
//or does not exist (has already been processed)
return true;
}
finally
{
if (stream != null)
stream.Close();
}
//file is not locked
return false;
}
}
By using GetThumnailImage you have to specify the width and height which is static.
Use the Load method instead.
eg: pictureBox1.Load(Path to the image); by using this u will have no problem in deleting the image or the folder before closing the app. no other methods need to be created.
hope this helps