I'm trying to convert images to insert into Microsoft Access Database in C#.Net Windows Form.
And also i want to delete and alter image.
But I don't know how to do that.
Please write a code segment for me.
I'd convert the image to a byte[] and. Then convert the byte[] back to an image.
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
public static Image ImageFromByte(byte[] image)
{
ImageConverter ic = new ImageConverter();
Image img = (Image)ic.ConvertFrom(image);
return img;
}
The following link will help you:
http://social.msdn.microsoft.com/forums/en-US/winformsdatacontrols/thread/c3fae255-9d2e-45e9-b830-58d544fc43ee/
Conversion will be in the following lines of the above link:
using ( FileStream fs = fi.OpenRead() )
{
bData = new byte[fi.Length];
int nReadLength = fs.Read( bData,0, (int)(fi.Length) );
}
Hope this helps...
using (var connection = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\BlankDatabase.mdb"))
{
connection.Open();
// Create table
using (var command = connection.CreateCommand())
{
command.CommandText = #"
CREATE TABLE FileTable (
FileName VARCHAR(255),
File IMAGE)
";
command.ExecuteNonQuery();
}
var imageContent = File.ReadAllBytes(#"C:\logo.png");
// upload image to the table
using (var command = connection.CreateCommand())
{
command.CommandText = #"
INSERT INTO FileTable (FileName, File)
VALUES (#FileName, #File)
";
command.Parameters.AddWithValue("#FileName", "Logo");
command.Parameters.AddWithValue("#File", imageContent);
command.ExecuteNonQuery();
}
// retreive image from the table
using (var command = connection.CreateCommand())
{
command.CommandText = #"
SELECT File
FROM FileTable
WHERE FileName = 'Logo'
";
var readImageContent = (byte[])command.ExecuteScalar();
File.WriteAllBytes(#"C:\logo1.png", readImageContent);
}
// alter image from the table
using (var command = connection.CreateCommand())
{
command.CommandText = #"
UPDATE FileTable
SET File = #File
WHERE FileName = 'Logo'
";
command.Parameters.AddWithValue("#File", imageContent);
command.ExecuteNonQuery();
}
// delete image from the table
using (var command = connection.CreateCommand())
{
command.CommandText = #"
DELETE FROM FileTable
WHERE FileName = 'Logo'
";
command.ExecuteNonQuery();
}
}
In this code BlankDatabase.mdb is an empty MS Access database file.
Related
I have this code:
private void LoginBTN_Click(object sender, EventArgs e)
{
var loguser = AutorizeLoginBox.Text;
var passuser = AutorizePasswordBox.Text;
SqlDataAdapter adapter = new SqlDataAdapter();
DataTable table = new DataTable();
string querystring = $"select ID, USERLOGIN, USERPASSWORD, USERAVATAR from USERTESTDB where USERLOGIN='{loguser}' and USERPASSWORD='{passuser}'";
SqlCommand command = new SqlCommand(querystring, sqldb.getConnection());
adapter.SelectCommand = command;
adapter.Fill(table);
if (table.Rows.Count == 1)
{
byte[] arr;
Image imgcur;
ImageConverter converter = new ImageConverter();
arr = (byte[])converter.ConvertFromString(table.Rows[0].ToString(), );
MemoryStream ms = new MemoryStream(arr);
Image i = Image.FromStream(ms);
Program.programpg.avatarbox.Image = i;
}
}
How to upload the image assigned to this user in the database after login. //symbolforfixdetails//symbolforfixdetails//symbolforfixdetails//symbolforfixdetails
This is how the database looks like:
Error is on this line:
arr = (byte[])converter.ConvertFromString(table.Rows[0].ToString() );
Error:
System.NotSupportedException: "ImageConverter cannot convert from System.String."
Try the following code to set the PictureBox.Image from image stored in SQL Server. The code is tested and works as intended.
Part 1: retrieve image from database and set it to PictureBox.Image:
DataTable table = new DataTable();
byte[] arr=null;
using (SqlConnection cn = new SqlConnection(cs))
{
cn.Open();
using (SqlDataAdapter ad = new SqlDataAdapter("select top 1 USERAVATAR from USERTESTDB", cn)) // Replace SQL query with yours
{
ad.Fill(table);
}
}
arr = (byte[])table.Rows[0][0];
// Replace it with [0][3] according to your posted query
System.Drawing.Bitmap bitmap = null;
ImageConverter converter = new ImageConverter();
System.Drawing.Image img =
(System.Drawing.Image)converter.ConvertFrom(arr);
bitmap = (System.Drawing.Bitmap)img;
pictureBox1.Image = bitmap;
Part 2: store image in database:
openFileDialog1.ShowDialog();
string path = openFileDialog1.FileName;
byte[] img = null;
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
img = br.ReadBytes((int)fs.Length);
using (SqlConnection cn = new SqlConnection(cs))
{
cn.Open();
using (SqlCommand cm = new SqlCommand("insert into USERTESTDB Values (#img)",cn))
{
cm.Parameters.Add(new SqlParameter("#img", img));
cm.ExecuteNonQuery();
}
}
You didn't asked about Part2, but I included it to ensure that the image is stored correctly (as binary data) in the database.
You have two problems with your line of code
arr = byte[])converter.ConvertFromString(table.Rows[0].ToString());
You used table.Rows[0] (which returns the entire row) instead of table.Rows[0][x] where x = the index of image column.
You can't convert String to Image in this way, check question 3594239 for more details.
Please Set your Db Column Data type to Varbinary(Max) which you store image's bytes.
Then read this binary to a MemoryStream() as you did but without convert.
If its a winforms project there should be an overload in PictureBox's DataSource (or whatever its name. if i don't remember wrong its name is Image or BackgroundImage) as it accepts directly byte array.
If Winforms, Either you can pass as byte array or Convert to an Image object and set it to datasource.
But if its a web project, then either you could set it as a base64 data/png string or Image object.
Hope this helps.
I want to add files to the database.
I have 6 columns to store files. If only 1 file is uploaded, I want to upload the single file in only one column. If two files are uploaded I want to use 2 columns.
What should my SQL query be to update accordingly when the files are uploaded?
I have restricted the number of files uploaded to 6 and their total size to 2 MB.
I'm using ASP.NET.
protected void btnUpload_Click(object sender, EventArgs e)
{
try
{
if (fileUpload.PostedFiles.Count <= 6)
{
int a = fileUpload.PostedFile.ContentLength;
if (a < 2000)
{
foreach (HttpPostedFile postedFile in fileUpload.PostedFiles)
{
string filename = Path.GetFileName(postedFile.FileName);
string contentType = postedFile.ContentType;
using (Stream fs = postedFile.InputStream)
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
using (SqlConnection con = new SqlConnection(#"Data Source= USER\SQLEXPRESS ; Initial Catalog= BlobUploading ; Integrated Security = True"))
{
string query = "insert into tblBlob values (#BloB1, #BloB2, #BloB3,#BloB4 ,#BloB5 ,#BloB6)";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#BloB1", bytes[0]);
cmd.Parameters.AddWithValue("#BloB2", bytes[1]);
cmd.Parameters.AddWithValue("#BloB3", bytes[2]);
cmd.Parameters.AddWithValue("#BloB4", bytes[3]);
cmd.Parameters.AddWithValue("#BloB5", bytes[4]);
cmd.Parameters.AddWithValue("#BloB6", bytes[5]);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
}
}
}
This is my update code, i know that inserting the values of bytes into the table is wrong!
Wrap your insert query into a Stored Procedure. In Stored Procedure, set the default value of Blob to Null.
From ASP.NET, set the blob parameters according to the availability of file. If you do not set a blob parameter, then it will be set to null in SP.
string strQuery = "sp_SaveFile";
SqlCommand cmd = new SqlCommand(strQuery);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#FormId", SqlDbType.Int).Value = fileId;
if(bytes1 != null)
cmd.Parameters.Add("#Blob1", SqlDbType.Binary).Value = bytes1;
if(bytes2 != null)
cmd.Parameters.Add("#Blob2", SqlDbType.Binary).Value = bytes2;
// .... Handle rest of the Blob parameters.
InsertUpdateData(cmd);
You need to redesign your database structure so that there is only one blob field, a record ID field as PK and a load identifier to identify which file if there are multiple files. Your insert query might look like:
INSERT INTO myTable
(
fileID,
fileContents
)
VALUES
(1, fileContent1),
(2 ,fileContent2)
You can then vary the number of added records depending on how many are needed.
Insert multiple rows, not multiple columns as #juharr says.
To do this in ASP.NET, C# you need structure to hold your files:
public class FileHolder
{
int FileID {get; set; }
byte[] FileData {get; set;}
}
Create a List<FileHolder> files to hold the data. Then:
foreach (var item in files)
{
// write item.FileID and item.FileData
// into your table
}
You are then not restricted to the number of files you can process at any one time.
protected void btnUpload_Click(object sender, EventArgs e)
{
try
{
if (fileUpload.PostedFiles.Count <= 6)
{
int a = fileUpload.PostedFile.ContentLength;
if (a < 2000)
{
foreach (HttpPostedFile postedFile in fileUpload.PostedFiles)
{
string filename = Path.GetFileName(postedFile.FileName);
string contentType = postedFile.ContentType;
using (Stream fs = postedFile.InputStream)
{
using (BinaryReader br = new BinaryReader(fs))
{
byte[] bytes = br.ReadBytes((Int32)fs.Length);
using (SqlConnection con = new SqlConnection(#"Data Source= USER\SQLEXPRESS ; Initial Catalog= BlobUploading ; Integrated Security = True"))
{
string query = "insert into tblBlob values (#BloB1, #BloB2, #BloB3,#BloB4 ,#BloB5 ,#BloB6)";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.AddWithValue("#BloB1", bytes[0]);
cmd.Parameters.AddWithValue("#BloB2", bytes[1]);
cmd.Parameters.AddWithValue("#BloB3", bytes[2]);
cmd.Parameters.AddWithValue("#BloB4", bytes[3]);
cmd.Parameters.AddWithValue("#BloB5", bytes[4]);
cmd.Parameters.AddWithValue("#BloB6", bytes[5]);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
}
}
}
}
}
This is my update code, i know that inserting the values of bytes into the table is wrong!
I am trying to insert an image into Postgres and retrieve that image from postgresql using C#.
I have two columns in my table: memberid (character varying) and member_photo (bytea)
Here is my code to insert the image:
using (FileStream pgFileStream = new FileStream("D:\\Capture.jpg", FileMode.Open, FileAccess.Read))
{
using (BinaryReader pgReader = new BinaryReader(new BufferedStream(pgFileStream)))
{
NpgsqlCommand command = new NpgsqlCommand();
byte[] ImgByteA = pgReader.ReadBytes(Convert.ToInt32(pgFileStream.Length));
command.CommandText = "insert into membermaster (memberid, member_photo) VALUES ('65', #Image)";
command.Connection = Program.conn;
Program.conn.Close();
Program.conn.Open();
//command.Parameters.Add(new NpgsqlParameter("Image", ImgByteA));
command.Parameters.Add("#Image", ImgByteA).Value = ImgByteA;
command.ExecuteNonQuery();
Program.conn.Close();
}
}
Here is my code to retrieve the image
NpgsqlCommand command = new NpgsqlCommand();
command.CommandText = "select member_photo from membermaster where memberid='65'";
command.Connection = Program.conn;
try
{
Program.conn.Close();
Program.conn.Open();
byte[] productImageByte = command.ExecuteScalar() as byte[];
if (productImageByte != null)
{
using (MemoryStream productImageStream = new System.IO.MemoryStream(productImageByte))
{
ImageConverter imageConverter = new System.Drawing.ImageConverter();
pictureBox1.Image = imageConverter.ConvertFrom(productImageByte) as System.Drawing.Image;
// image.Save(imageFullPath, System.Drawing.Imaging.ImageFormat.Jpeg);
pictureBox1.Image = System.Drawing.Image.FromStream(productImageStream);
}
}
}
catch
{
Program.conn.Close();
throw;
}
The code to insert the image is working fine, but I can't show this image in a picturebox.
I get an error :
Parameter is not valid
Please help me solve this problem
AFAIK you cannot retrieve a byte[] using ExecuteScalar. You should use ExecuteReader instead. Just to be on the safe side when inserting parameters, I prefer to specify types myself, so my insert looks like this:
using (var conn = new NpgsqlConnection(connString))
{
string sQL = "insert into picturetable (id, photo) VALUES(65, #Image)";
using (var command = new NpgsqlCommand(sQL, conn))
{
NpgsqlParameter param = command.CreateParameter();
param.ParameterName = "#Image";
param.NpgsqlDbType = NpgsqlTypes.NpgsqlDbType.Bytea;
param.Value = ImgByteA;
command.Parameters.Add(param);
conn.Open();
command.ExecuteNonQuery();
}
}
I can then retrieve and load the image like this:
using (var conn = new NpgsqlConnection(connString))
{
string sQL = "SELECT photo from picturetable WHERE id = 65";
using (var command = new NpgsqlCommand(sQL, conn))
{
byte[] productImageByte = null;
conn.Open();
var rdr = command.ExecuteReader();
if (rdr.Read())
{
productImageByte = (byte[])rdr[0];
}
rdr.Close();
if (productImageByte != null)
{
using (MemoryStream productImageStream = new System.IO.MemoryStream(productImageByte))
{
ImageConverter imageConverter = new System.Drawing.ImageConverter();
pictureBox1.Image = imageConverter.ConvertFrom(productImageByte) as System.Drawing.Image;
}
}
}
}
I do not know if specifying the datatype on insert makes any difference, so try just retrieving using a Reader first. If that doesn't work, then I suggest changing your insert routine to something like mine.
Please note in my example id is an integer, not a character varying!
While the code in the accepted answer is working, it is not true that you cannot use ExecuteScalar. It might have been an issue in older versions, but using Npgsql 6.0.7 the following works:
public static async Task<byte[]?> GetByteaAsync(int id, string connectionString) {
byte[]? result = null;
await using (var con = new NpgsqlConnection(connectionString)) {
await con.OpenAsync();
await using (var cmd = new NpgsqlCommand("SELECT field_name from table_name where id=#id", con) {CommandType = CommandType.Text}) {
cmd.Parameters.Add("#id", NpgsqlDbType.Integer).Value = id;
result = ((byte[]?) await cmd.ExecuteScalarAsync());
}
await con.CloseAsync();
}
return result;
}
In C#, I am trying to save and load an image. I am saving it into a mysql database (type longblob) and trying to load it back into an picture box. The problem i keep getting is the error "Parameter is not valid", see code below
ConnectionClass Sqlconnection = new ConnectionClass();
Sqlconnection.ConnectionOpen();
OdbcCommand cmd = new OdbcCommand("Insert into pictest(pic) values('"+ Encoding.Unicode.GetBytes(richTextBox1.Rtf) + "')", Sqlconnection.connection);
int num = cmd.ExecuteNonQuery();
MessageBox.Show(num + " Rows inserted ");
Sqlconnection.ConnectionClose();
OdbcDataReader rd = null;
try
{
Sqlconnection.ConnectionOpen();
string query = "select * from pictest where id = 1";
cmd = new OdbcCommand(query, Sqlconnection.connection);
rd = cmd.ExecuteReader();
if (rd.Read())
{
byte[] bytes = (byte[])rd[1];
ImageConverter converter = new ImageConverter();
pictureBox1.Image = Image.FromStream(new MemoryStream(bytes)); <--Parameter is not valid
pictureBox1.Refresh();
pictureBox1.Image = Encoding.Unicode.GetString(bytes);
}
Sqlconnection.ConnectionClose();
rd.Close();
}
catch (Exception asd)
{
MessageBox.Show("Problem " + asd.Message);
Sqlconnection.ConnectionClose();
if (rd != null)
{
rd.Close();
}
}
what exact is the problem? Is the image not saving correctly? it should be as it is saving to a longblob. The record for the image says System.Byte[]
you should be able to inspect (via the debugger) the values inside OdbcDataReader before trying to cast the first field to byte[]. Take a look at what type is actually stored in the OdbcDataReader
Using SELECT * is problematic performance wise. It also leaves your rd[1] up for interpretation. If the order of columns ever changes, your code could break. Use rd["your_column_name"] to access the values. As of right now I can't tell if index 1 is correct due to the SELECT * and non-named indexing into the Items array.
First of all why you need to store image in MySql?
Why not in physical drive? If its not a crucial data go for saving it in physical drive.
However, here is code to retrieve:
public byte [] getImage(int imageNumber)
{
string strSql = "SELECT * FROM File";
DataSet ds = new DataSet("Image");
OdbcDataAdapter tempAP = new OdbcDataAdapter(strSql,this._objConn);
OdbcCommandBuilder objCommand = new OdbcCommandBuilder(tempAP);
tempAP.Fill(ds,"Table");
try
{
this._objConn.Open();
byte [] buffer = (byte [])ds.Tables["Table"].Rows[imageNumber]["Data"];
return buffer;
}
catch{this._objConn.Close();return null;}
finally{this._objConn.Close();}
}
Courtesy:
http://www.codeproject.com/Articles/6750/Storing-Images-in-MySQL-using-ASP-NET
For physical drive
http://www.codeproject.com/Articles/2113/C-Photo-Album-Viewer
I'm trying to create sql database that contains
Image Id (int)
Imagename (varchar(50))
Image (image)
and in aspx write in upload button this code:
protected void btnUpload_Click(object sender, EventArgs e)
{
//Condition to check if the file uploaded or not
if (fileuploadImage.HasFile)
{
//getting length of uploaded file
int length = fileuploadImage.PostedFile.ContentLength;
//create a byte array to store the binary image data
byte[] imgbyte = new byte[length];
//store the currently selected file in memeory
HttpPostedFile img = fileuploadImage.PostedFile;
//set the binary data
img.InputStream.Read(imgbyte, 0, length);
string imagename = txtImageName.Text;
//use the web.config to store the connection string
SqlConnection connection = new SqlConnection(strcon);
connection.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Image (ImageName,Image) VALUES (#imagename,#imagedata)", connection);
cmd.Parameters.Add("#imagename", SqlDbType.VarChar, 50).Value = imagename;
cmd.Parameters.Add("#imagedata", SqlDbType.Image).Value = imgbyte;
int count = cmd.ExecuteNonQuery();
connection.Close();
if (count == 1)
{
BindGridData();
txtImageName.Text = string.Empty;
ScriptManager.RegisterStartupScript(this, this.GetType(), "alertmessage", "javascript:alert('" + imagename + " image inserted successfully')", true);
}
}
}
When I'm uploading a new image I need to first check if this image already exists in database and if it doesn't exist save that in database.
Please how I can do that?
Add a method that is responsible for checking if the filename already exists in the table.
private bool FileExists(string imageName)
{
using (SqlConnection conn = new SqlConnection()) // establish connection
{
using (SqlCommand cmd =
new SqlCommand("select 1 where exists(select Id from Image where ImageName = #)", conn))
{
cmd.Parameters.Add("#imagename", SqlDbType.VarChar, 50).Value = imageName;
return cmd.ExecuteNonQuery() > 0;
}
}
}
Then I would call this like so
if (fileuploadImage.HasFile && !FileExists(txtImageName.Text))
{
...
string cmd ="if not exists (select * from Image where ImageName= #imagename); ";
\\if you want to check image data
\\ (select * from Image where SUBSTRING(ImageName, 1, 8000)= SUBSTRING(#imagename, 1, 8000) );
string cmd += "INSERT INTO Image (ImageName,Image) VALUES (#imagename,#imagedata)";
SqlCommand cmd = new SqlCommand(cmd, connection);
If you want to verify imagedata, You can try to use DATALENGTH as first line of check for the two images.
If the DATALENGTH is different, then you suppose to have a "different" picture".
You can also use SUBSTRING(Image, 1, 8000) to check first 8000 bytes.
And also SUBSTRING(Image, DATALENGTH(Image) - 7999, 8000) to check last 8000 bytes.
One of the fastest ways is to do an UPDATE and then INSERT if update returns no updates.
string cmd = #"UPDATE Image SET Image = #imagedata WHERE ImageName = #ImageName
IF ##ROWCOUNT=0
INSERT INTO Image (ImageName,Image) VALUES (#imagename,#imagedata)";
Or if query on Image itself:
string cmd = #"UPDATE Image SET ImageName = #ImageName WHERE Image = #imagedata
IF ##ROWCOUNT=0
INSERT INTO Image (ImageName,Image) VALUES (#imagename,#imagedata)";