I want get an image from a Blob in MySQL then display image in a PictureBox. My incoming image is not correct and I don't understand how I can retrieve the byte array because my current array is not correct.
My code:
add img into database:
using(OpenFileDialog ofd = new OpenFileDialog())
{
if (ofd.ShowDialog() == DialogResult.OK)
{
byte[] bytes = File.ReadAllBytes(ofd.FileName);
imageUrl = ofd.FileName.ToString();
//roundPictureBox1.Image = Image.FromFile(ofd.FileName);
roundPictureBox2.ImageLocation = imageUrl;
MySqlConnection con = new MySqlConnection(connectionString);
con.Open();
MySqlCommand cmd = new MySqlCommand("INSERT INTO reg.img_table(image, id) VALUES (#image, #id)", con);
long id = cmd.LastInsertedId;
Properties.Settings.Default.idImg = id;
cmd.Parameters.AddWithValue("#image", bytes);
cmd.Parameters.AddWithValue("#id", id);
cmd.ExecuteNonQuery();
con.Close();
}
}
return Img:
private Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
main code:
private void photoLoad()
{
string connectionString = "datasource=localhost;" +
"port=3306;" +
"database=reg;" +
"username=root;" +
"password=Admin123";
MySqlConnection con = new MySqlConnection(connectionString);
byte[] ImageByte = new byte[0];
string query1 = "select image from reg.img_table where id= #id";
MySqlCommand cmd = new MySqlCommand(query1, con);
cmd.Parameters.AddWithValue("#id", Properties.Settings.Default.idImg);
try
{
con.Open();
MySqlDataReader row;
row = cmd.ExecuteReader();
while (row.Read())
{
ImageByte = (Byte[])(row["image"]);
}
if (ImageByte != null)
{
// You need to convert it in bitmap to display the image
roundPictureBox1.Image = byteArrayToImage(ImageByte);
roundPictureBox1.Refresh();
}
}
catch (Exception ex)
{
MessageBox.Show("Error Img");
}
}
An error doesn't show. The login form shows but PictureBox doesn't show the photo.
According to your OP, you're storing your image in a database BLOB column in a MySql database. The following shows how to insert an image into a MySql database table. Then retrieve that image and display it in a PictureBox.
Download/install NuGet package: MySql.Data
Database Table: Student
I've chosen to store the connection string for the database in App.config.
App.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<connectionStrings>
<add name="MySqlConnectionString" connectionString="Server=localhost;Port=3306;Database=University123;Uid=testAdmin;Pwd=password123;" />
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>
Create a class: (name: HelperMySql.cs)
In VS menu, click Project
Select Add Class...
Add the following using statements:
using System.Configuration;
using System.IO;
using MySql.Data.MySqlClient;
HelperMySql.cs
Note: I've chosen to use LongBlob instead of Blob - this can be changed, if desired.
public class HelperMySql
{
private string _connectionStr = ConfigurationManager.ConnectionStrings["MySqlConnectionString"].ConnectionString;
//private string _connectionStr = "Server=localhost;Port=3306;Database=University123;Uid=testAdmin;Pwd=password123;";
public void ExecuteNonQuery(string sqlText)
{
using (MySqlConnection con = new MySqlConnection(_connectionStr))
{
//open
con.Open();
using (MySqlCommand cmd = new MySqlCommand(sqlText, con))
{
//execute
cmd.ExecuteNonQuery();
}
}
}
public byte[] GetImageAsByteArray(string filename)
{
//reads image from file and returns as byte[]
if (String.IsNullOrEmpty(filename))
throw new Exception("Error (GetImageAsByteArray) - Filename not specified.");
else if(!File.Exists(filename))
throw new Exception($"Error (GetImageAsByteArray) - File '{filename}' doesn't exist.");
return System.IO.File.ReadAllBytes(filename);
}
public void TblStudentCreate()
{
//for mySQL, use backticks (ex: `First Name`) if tablename has space in it
string sqlText = #"CREATE TABLE Student (Id int NOT NULL AUTO_INCREMENT,
FirstName varchar(50),
LastName varchar(75),
Img longblob,
CONSTRAINT PK_Student_ID PRIMARY KEY(ID));";
ExecuteNonQuery(sqlText);
Debug.WriteLine("Info: Table created (Student)");
}
public void TblStudentInsert(string firstName, string lastName, string filename)
{
if (String.IsNullOrEmpty(filename))
throw new Exception("Error (TblStudentInsert) - Filename not specified.");
else if (!File.Exists(filename))
throw new Exception($"Error (TblStudentInsert) - File '{filename}' doesn't exist.");
byte[] imageBytes = File.ReadAllBytes(filename);
TblStudentInsert(firstName, lastName, imageBytes);
}
public void TblStudentInsert(string firstName, string lastName, byte[] imageBytes)
{
string sqlText = "INSERT INTO Student (FirstName, LastName, Img) VALUES (#firstName, #lastName, #imageBytes);";
using (MySqlConnection con = new MySqlConnection(_connectionStr))
{
//open
con.Open();
using (MySqlCommand cmd = new MySqlCommand(sqlText, con))
{
//add parameters
//FirstName
if (!String.IsNullOrEmpty(firstName))
cmd.Parameters.Add("#firstName", MySqlDbType.VarChar).Value = firstName;
else
cmd.Parameters.Add("#firstName", MySqlDbType.VarChar).Value = DBNull.Value;
//LastName
if (!String.IsNullOrEmpty(lastName))
cmd.Parameters.Add("#lastName", MySqlDbType.VarChar).Value = lastName;
else
cmd.Parameters.Add("#lastName", MySqlDbType.VarChar).Value = DBNull.Value;
//Img
if (imageBytes != null)
cmd.Parameters.Add("#imageBytes", MySqlDbType.LongBlob).Value = imageBytes;
else
cmd.Parameters.Add("#imageBytes", MySqlDbType.LongBlob).Value = DBNull.Value;
//execute
cmd.ExecuteNonQuery();
}
}
}
public byte[] GetStudentImage(int id)
{
string sqlText = "SELECT img from Student where Id = #id;";
using (MySqlConnection con = new MySqlConnection(_connectionStr))
{
//open
con.Open();
using (MySqlCommand cmd = new MySqlCommand(sqlText, con))
{
cmd.Parameters.Add("#id", MySqlDbType.Int32).Value = id;
//execute
using (MySqlDataReader dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
while(dr.Read())
{
//get image from database and return as byte[]
if (dr["Img"] != null && dr["Img"] != DBNull.Value)
return (byte[])dr["Img"];
}
}
}
}
}
return null;
}
}
Usage: Insert Record to Database
private HelperMySql helper = new HelperMySql();
...
helper.TblStudentInsert("John", "Smith", #"D:\Images\Students\JohnSmith.png");
Usage: Display Image in PictureBox (name: pictureBox1)
int studentId = 1;
byte[] imageBytes = helper.GetStudentImage(studentId);
using (MemoryStream ms = new MemoryStream(imageBytes))
{
pictureBox1.Image = Image.FromStream(ms);
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; //fit to size
pictureBox1.Refresh();
}
Note: You may consider storing the filenames in the database, and store the actual files in the file system instead.
Resources:
MySQL 8.0 Reference Manual
Data Type Storage Requirements
Related
I am trying to use this code:
var connString = "Server=localhost\\SQLEXPRESS;Integrated Security = SSPI; database = master";
string cmdText = "CREATE DATABASE #userDatabase";
using (var sqlConnection = new SqlConnection(connString))
{
using (var sqlCmd = new SqlCommand(cmdText, sqlConnection))
{
sqlCmd.Parameters.Add("#userDatabase", System.Data.SqlDbType.NVarChar).Value = databaseName;
sqlConnection.Open();
sqlCmd.ExecuteNonQuery();
}
}
I get an error on sqlCmd:
'Incorrect syntax near '#userDatabase'
However, when I add the database using dynamic SQL code, I get no errors and the query runs perfectly (I heard that will be dangerous though).
You can create a dynamic query to perform this.
private void SetupDatabase(string dbFolder, string dbName)
{
if (Directory.Exists(String.Format("{0}\\db", dbFolder)) == false)
{
Directory.CreateDirectory(String.Format("{0}\\db", dbFolder));
}
if (File.Exists(String.Format("{0}\\db\\{1}_Data.mdf", dbFolder, dbName)) == false)
{
ExecuteQuery(
"master",
String.Format("CREATE DATABASE {1} ON PRIMARY (NAME = {1}_Data, FILENAME = '{0}\\db\\{1}_Data.mdf', SIZE = 2MB, FILEGROWTH = 10%) LOG ON (NAME = {1}_Log, FILENAME = '{0}\\db\\{1}_Log.ldf', SIZE = 1MB, MAXSIZE = 5MB, FILEGROWTH = 10%)", dbFolder, dbName));
}
}
private void ExecuteQuery(
string db,
string query)
{
SqlConnection connection = null;
try
{
connection = new SqlConnection(string.Format(connectionString, db));
connection.Open();
// Creates DB
using (SqlCommand command = new SqlCommand(query, connection))
{
command.ExecuteNonQuery();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
connection.Close();
}
}
I am trying to display pictures from my SQLSEVER database on my website. My users have a picture field with a picture datatype. If the picture column is null, then I want the picture displayed to be a egg.jpg, but right now for every person their picture is egg.jpg, even if they have a picture in the database. Here is my method.
public string getImageUrl()
{
System.Data.SqlClient.SqlConnection sc = new System.Data.SqlClient.SqlConnection();
sc.ConnectionString = "Server =MRCOMPUTER2\\SQLEXPRESS; Database = WBL;Trusted_Connection=Yes;";
sc.Open();
System.Data.SqlClient.SqlCommand insert = new System.Data.SqlClient.SqlCommand();
insert.Connection = sc;
insert.CommandText = "SELECT profilePicture from SystemUser";
insert.ExecuteNonQuery();
SqlDataReader reader = insert.ExecuteReader();
string url = "";
while (reader.Read())
{
if ( !DBNull.Value.Equals(reader[0]))
{
url = "data:Image / png; base64," + Convert.ToBase64String((byte[])reader[0]);
}
else {
url = "images/egg.jpg";
}
}
return url;
}
Your code returns the image for the last user in your table.
Here:
insert.CommandText = "SELECT profilePicture from SystemUser";
you select all users from the table (not just the one you currently show). Then:
while (reader.Read())
{
...
url = ...
...
}
you re-assign url inside every iteration of your while loop. This is semantically equivalent to:
url = ... /* The value determined from the last record of the reader. */
Thus, all your users show the same image - the one of the last user in your table.
You SELECT statement is attached into a ExecuteNonQuery?
Take it off.
Just perform the READER statement...
Try this:
static void Main(string[] args)
{
string connectionString = "Server=.;Database=AA;Trusted_Connection=True;";
/*
CREATE TABLE [dbo].[SystemUser]
(
[ProfilePicture] [varbinary](max) NULL
)
*/
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = #"
INSERT [AA].[dbo].[SystemUser] ([ProfilePicture]) VALUES (#ProfilePicture);
INSERT [AA].[dbo].[SystemUser] ([ProfilePicture]) VALUES (NULL);
";
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
byte[] bytes = File.ReadAllBytes(#"1.jpg");
command.Parameters.AddWithValue("#ProfilePicture", bytes);
connection.Open();
command.ExecuteNonQuery();
}
DataSet ds = new DataSet();
using (SqlConnection connection = new SqlConnection(connectionString))
{
string sql = #"
SELECT TOP 1000 [ProfilePicture] FROM [AA].[dbo].[SystemUser];
";
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandText = sql;
command.CommandType = CommandType.Text;
connection.Open();
SqlDataAdapter da = new SqlDataAdapter(command);
da.Fill(ds);
}
var rows = ds.Tables[0].Rows.Cast<DataRow>();
foreach (DataRow row in rows)
{
byte[] bytes = row.Field<byte[]>(0);
if (bytes != null)
{
string fileName = Guid.NewGuid().ToString("N") + ".jpg";
File.WriteAllBytes(fileName, bytes);
}
}
}
Can you try using the name of the column such as
var Val = (String)reader["column name"];
Also, try something like this to test:
while (reader.Read())
{
var testVal = reader.GetString(0);
Var testVal2 = reader.GetString(1);
I have ASP MVC app, MS SQL and C#. I download a file to MS SQL, then I upload the file from DB. After this the file become unreadable. I can't understand what happens. Below code, which returns the file to client.
public string CreateFile(HttpPostedFileBase file)
{
string stream_id = String.Empty;
try
{
int size = file.ContentLength;
string name = file.FileName;
string contentType = file.ContentType;
byte[] bytes = new byte[size];
file.InputStream.Read(bytes, 0, size);
string constr = ConfigurationManager.ConnectionStrings["PokrovConnectionString"].ConnectionString;
using (TransactionScope ts = new TransactionScope())
{
using (SqlConnection con = new SqlConnection(constr))
{
string query = "DECLARE #MyTableVar TABLE (stream_id uniqueidentifier);"
+ "INSERT INTO Files(name, file_stream) OUTPUT INSERTED.stream_id INTO #MyTableVar VALUES(#name, #file_stream);"
+ "SELECT TOP (1) #Identity = stream_id FROM #MyTableVar;";
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.Connection = con;
cmd.Parameters.Add("#name", SqlDbType.VarChar).Value = Path.GetFileName(file.FileName);
cmd.Parameters.Add("#file_stream", SqlDbType.VarBinary).Value = bytes;
SqlParameter idParam = cmd.Parameters.Add("#Identity", SqlDbType.NVarChar, 1000);
idParam.Direction = ParameterDirection.Output;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
stream_id = (string)idParam.Value;
}
}
ts.Complete();
}
}
catch { }
return stream_id;
}
public FileContentResult GetFile(Guid stream_id, string contentType = "application/octet-stream")
{
SqlDataReader rdr;
byte[] fileContent = null;
string mimeType = "";
string fileName = "";
string connect = onfigurationManager.ConnectionStrings["PokrovConnectionString"].ConnectionString;
bool success = false;
using (var conn = new SqlConnection(connect))
{
var qry = "SELECT file_stream, name, file_type FROM Files WHERE stream_id = #stream_id";
var cmd = new SqlCommand(qry, conn);
cmd.Parameters.AddWithValue("#stream_id", stream_id);
conn.Open();
try
{
rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
rdr.Read();
fileContent = (byte[])rdr["file_stream"];
mimeType = rdr["file_type"].ToString();
fileName = rdr["name"].ToString();
}
success = true;
}
catch
{
return null;
}
}
if (success == true)
{
FileContentResult newFile = new FileContentResult(fileContent, contentType);
newFile.FileDownloadName = fileName;
return newFile;
}
return null;
}
From looking at the code which stores posted file into database - most probably you forgot to copy actual file content, just initialized empty byte array with length of posted file, and saved it into db.
.Net has a class which can help you save stream into sql server without allocating buffer and reading entire stream first - SqlBytes. Try to replace this line:
byte[] bytes = new byte[file.ContentLength];
With this:
SqlBinary bytes = new SqlBinary(file.InputStream);
You can also take a look at SqlBinary usage in this post.
I want to retrieve image from oracle database
and show it in Image control I tried but it is showing empty image
Code for Insert Image:
protected void btnUpload_Click(object sender, EventArgs e)
{
int imgLength = 0;
string imgContentType = null;
string imgFileName = null;
Stream imgStream = FileUpload.PostedFile.InputStream;
imgLength = FileUpload.PostedFile.ContentLength;
imgContentType = FileUpload.PostedFile.ContentType;
imgFileName = FileUpload.PostedFile.FileName;
if (imgContentType == "image/jpeg" || imgContentType == "image/gif" ||
imgContentType == "image/pjpeg"
|| imgContentType == "image/bmp")
{
OracleConnection DbConnection = new OracleConnection(con1);
DbConnection.Open();
FileStream fls;
fls = new FileStream(#imgFileName, FileMode.Open, FileAccess.Read);
byte[] blob = new byte[fls.Length];
fls.Read(blob, 0, System.Convert.ToInt32(fls.Length));
fls.Close();
string query = "insert into image(id,name,photo) values(1,'" + imgFileName + "'," + " :BlobParameter )";
// Establish a new OracleCommand
OracleCommand cmd = new OracleCommand();
cmd.CommandText = query;
cmd.Connection = DbConnection;
cmd.CommandType = CommandType.Text;
System.Data.OracleClient.OracleParameter paramImage = new System.Data.OracleClient.OracleParameter("image",
Oracle.DataAccess.Client.OracleDbType.Blob);
paramImage.ParameterName = "BlobParameter";
paramImage.Value = blob;
paramImage.Direction = ParameterDirection.Input;
cmd.Parameters.Add(paramImage);
cmd.ExecuteNonQuery();
}
}
Table:
Id Name Photo
1 C:\Document\Image\Ocean.jpeg (BLOB)
In the below code I'm trying to retrieve and show that image in image control
but it's not working
Code for retrieve:
void GetImagesFromDatabase()
{
try
{
OracleConnection DbConnection = new OracleConnection(con1);
DbConnection.Open();
OracleCommand cmd = new OracleCommand("Select name from Image", DbConnection);
OracleDataReader oda = cmd.ExecuteReader();
while (oda.Read())
{
string path = oda[0].ToString();
img.ImageUrl = path;
}
}
catch (Exception ex)
{
}
}
Any ideas? Thanks in advance
I want this button's image use the image stored in database (image path)...
private void button15_Click(object sender, EventArgs e)
{
string a = button11.Text;
string connString = "Server=Localhost;Database=test;Uid=*****;password=*****;";
MySqlConnection conn = new MySqlConnection(connString);
MySqlCommand command = conn.CreateCommand();
command.CommandText = ("Select link from testtable where ID=" + a);
try
{
conn.Open();
}
catch (Exception ex)
{
//button11.Image = ex.ToString();
}
MySqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
button11.Image = reader["path"].ToString();
}
}
I think the error lies in "reader["path"].ToString();" but I don't know what syntax to use.
If you stored the path to the image file on the disk in the path column, you should laod the image:
string path = (string)reader["path"];
button11.Image = Image.FromFile(path);
Side note: Never pass the values directly from a user input to a database query. It is vulnerable to sql injection attacks. Use parameters instead:
command.CommandText = "Select link from testtable where ID=#id";
command.Parameters.AddWithValue("#id", int.Parse(a));
try this:
while (reader.Read())
{
string path = reader.GetString(0);
button11.Image = Image.FromFile(path);
}
Try this: ( Written right to answer box, may be there are typo! )
private void button15_Click(object sender, EventArgs e)
{
string a = button11.Text;
string imagePath;
string connString = "Server=Localhost;Database=test;Uid=root;password=root;";
using(MySqlConnection conn = new MySqlConnection(connString))
using(MySqlCommand command = conn.CreateCommand())
{
command.CommandText = "Select link from testtable where ID=#id";
command.Parameters.AddWithValue("#id", int.Parse(a));
try
{
conn.Open();
imagePath= (string)command.ExecuteScalar();
}
catch (Exception ex)
{
//button11.Image = ex.ToString();
}
button11.Image = Image.FromFile(imagePath);
}
}