Save and retrieve images from mysql database - c#

For Save Image I am try this code.
MySqlConnection mycon = new MySqlConnection(string.Format("Server=127.0.0.1;Port=3306;Database=test;Uid=root;Pwd=123456;"));
mycon.Open()
FileStream fs = new FileStream("b.jpg", FileMode.Open, FileAccess.Read);
int sizee = (int)fs.Length;
byte[] rawData = new byte[sizee+1];
fs.Read(rawData, 0, sizee);
fs.Close();
new MySqlCommand(string.Format("INSERT INTO image VALUES(NULL,'{0}',{1})", rawData, sizee), mycon).ExecuteNonQuery();
This code is work fine and insert data successfully.But when i trying to retrieve data it throw an exception No imaging component suitable to complete this operation was found.
Here is the code which is use to retrieve data.
MySqlConnection mycon = new MySqlConnection(string.Format("Server=127.0.0.1;Port=3306;Database=test;Uid=root;Pwd=123456;"));
mycon.Open();
MySqlCommand mycom = new MySqlCommand("Select * from image", mycon);
MySqlDataReader myData = mycom.ExecuteReader();
myData.Read();
int filesize = myData.GetInt32(myData.GetOrdinal("size"));
byte[] mydatya=new byte[filesize];
myData.GetBytes(myData.GetOrdinal("myImage"), 0, mydatya, 0, filesize);
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = new MemoryStream(mydatya);
bitmapImage.EndInit();

It is generally considered better practice to put only references to files in a database and physically save the files in a folder.

Related

Get varbinary image into C# DataSet with SqlDataReader

SqlDataAdapter has the .Fill(dataset) function, but SqlDataReader doesn't.
This should extract the image and place it inside my byte[]
while (reader.Read())
{
listOfProfiles.Add(new Profile
{
ProfileImage = (byte[])profileReader["imageFile"]
});
I've tried to create a DataSet and create a row where the image should be
DataSet ds = new DataSet();
byte[] MyData = new byte[0];
DataTable table0 = new DataTable("table0", "table0");
table0.Columns.Add("imageFile"); // DB column name
table0.Rows.Add(listOfProfiles[0].ProfileImage);
ds.Tables.Add(table0);
DataRow myRow;
After the image is in my DataSet, I tried converting it to a BitmapImage, but got the following error:
Unable to cast object of type 'System.String' to type 'System.Byte[]'.'
This is the code that should convert the varbinary image from the database to a BitmapImage:
if (ds.Tables[0].Rows.Count == 1)
{
myRow = ds.Tables[0].Rows[0];
MyData = (byte[])myRow["imageFile"];
MemoryStream stream = new MemoryStream(MyData);
stream.Write(MyData, 0, MyData.Length);
stream.Position = 0;
System.Drawing.Image img =
System.Drawing.Image.FromStream(stream);
BitmapImage bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
bi.StreamSource = ms;
bi.EndInit();
hpProfileImage.Source = bi;
}
Any help is very appreciated
A working example of loading image from database in WPF
private void LoadLoggedInUsersDetails()
{
con.Open();
SqlCommand cmd2 = new SqlCommand("Select * from userinfo where ID='" + idStringHere + "'", con);
byte[] photo;
SqlDataReader dr2 = cmd2.ExecuteReader;
while (dr2.Read)
{
photo = (byte[])dr2(11);
MemoryStream strm = new MemoryStream(photo);
BitmapImage bi = new BitmapImage;
bi.BeginInit();
strm.Seek(0, SeekOrigin.Begin);
bi.StreamSource = strm;
bi.EndInit();
imageControl.ImageSource = bi;
}
con.Close();
}
A quick explanation : First i am declaring a byte[] variable.Then,as the SqlDatareader starts to read data from the database,the byte[] variable gets it's value from the datareader's specific column/cell.Then i declare a MemoryStream which reads the byte[].Now we declare a BitmapImage variable.BeginInIt and EndInIt are essential in this case.To make sure the Memorystream's position is at the beginning,we use strm.Seek(0, SeekOrigin.Begin).The bitmapImage uses that MemoryStream as a StreamSource.Finally we call EndInIt and do whatever we want to do with the bitmap , in this case,use it as a ImageBrush's ImageSource

Saving to disc directyl from sqlFileStream or figuring out how to store large data inside one byte array

Hello I have been following numerous tutorials online for a new project I'm working on. I am obtaining my data from filestream and I'm getting an out of memory exception at this line:
byte[] buffer = new byte[(int)sfs.Length];
What I'm doing is immediately taking the byte array and then wanting to save it to the disc. If there is not an easy way to avoid the system out of memory exception, is there a way to write to disc from the sqlFileStream avoiding creating a new byte array?
string cs = #”Data Source=<your server>;Initial Catalog=MyFsDb;Integrated Security=TRUE”;
using (SqlConnection con = new SqlConnection(cs))
{
con.Open();
SqlTransaction txn = con.BeginTransaction();
string sql = “SELECT fData.PathName(), GET_FILESTREAM_TRANSACTION_CONTEXT(), fName FROM MyFsTable”;
SqlCommand cmd = new SqlCommand(sql, con, txn);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
string filePath = rdr[0].ToString();
byte[] objContext = (byte[])rdr[1];
string fName = rdr[2].ToString();
SqlFileStream sfs = new SqlFileStream(filePath, objContext, System.IO.FileAccess.Read);
**byte[] buffer = new byte[(int)sfs.Length];**
sfs.Read(buffer, 0, buffer.Length);
sfs.Close();
string filename = #”C:\Temp\” + fName;
System.IO.FileStream fs = new System.IO.FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.Write);
fs.Write(buffer, 0, buffer.Length);
fs.Flush();
fs.Close();
}
rdr.Close();
txn.Commit();
con.Close();
}
}
Here's a method that can be used to read bytes from one Stream to another Stream without regard for what type of Stream they each are.
Public Sub CopyStream(source As Stream, destination As Stream, Optional blockSize As Integer = 1024)
Dim buffer(blockSize - 1) As Byte
'Read the first block.'
Dim bytesRead = source.Read(buffer, 0, blockSize)
Do Until bytesRead = 0
'Write the current block.'
destination.Write(buffer, 0, bytesRead)
'Read the next block.'
bytesRead = source.Read(buffer, 0, blockSize)
Loop
End Sub

How to save the image to the database after streaming it from an IP camera?

I have a code to stream a snapshot from an IP camera and save it on harddisk.
Then I have another code to read it and store it in ms-sql database.
I know that it will be more faster if I just stream the image and save it in the database without saving it on the harddisk and read it again. But I don't know how to merge this.
Code to get the image
string sourceURL = "http://" + ip + "/cgi-bin/cmd/encoder?SNAPSHOT";
WebRequest req = (WebRequest)WebRequest.Create(sourceURL);
req.Credentials = new NetworkCredential("admin", "123456");
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
Bitmap bmp = (Bitmap)Bitmap.FromStream(stream);
bmp.Save(ImagePath);
Then to insert the image to the database:
byte[] imageData = ReadFile(ImageName);
using (SqlConnection cn = new SqlConnection(constr))
{
string qry = "update vaiolations set val_image=#ImageData ,valid=1 where id=#OriginalPath ";
SqlCommand SqlCom = new SqlCommand(qry, cn);
SqlCom.Parameters.Add(new SqlParameter("#OriginalPath", (object)id));
SqlCom.Parameters.Add(new SqlParameter("#ImageData", (object)imageData));
cn.Open();
SqlCom.ExecuteNonQuery();
cn.Close();
cn.Dispose();
}
byte[] ReadFile(string sPath)
{
using (FileStream fStream = new FileStream(sPath, FileMode.Open, FileAccess.Read))
{
byte[] data = null;
FileInfo fInfo = new FileInfo(sPath);
long numBytes = fInfo.Length;
BinaryReader br = new BinaryReader(fStream);
data = br.ReadBytes((int)numBytes);
return data;
}
}
How can I combine these two code snippets to stream the image and then immediately insert it into the database?
Why are you converting the incoming bytes to a Bitmap?
You could probably just read the stream to a memory stream, and pass it on to the database:
Stream stream = resp.GetResponseStream();
byte[] data;
using (MemoryStream ms = new MemoryStream())
{
int num_bytes = 0;
byte[] temp = new byte[4096];
while ((num_bytes = stream.Read(temp, 0, temp.Length)) > 0)
ms.Write(temp, 0, bytes);
data = ms.ToArray();
}
Then pass data to your database.

NEED HELP.crop image while streaming it from IP cam

I have a monitoring system and I want to save a snapshot from a camera when alarm trigger. I have tried many methods to do that…and it’s all working fine.
string ImageName = #"E:\snapshot\pic" + imageid + ".jpg";
WebClient webclient = new WebClient();
webclient.Credentials = new NetworkCredential("admin", "pass");
Uri url = new Uri("http://" + ip + "/cgi-bin/cmd/encoder?SNAPSHOT");
webclient.DownloadFileAsync(url, ImageName);
webclient.Dispose();
the image coming from the cam is(1280*1024). i want to crop the image to get (500*500) Pixel
private void button2_Click(object sender, EventArgs e)
{
string ImageFrom = #"c:\3.jpg";
byte[] imageData = ReadFile(ImageFrom);
byte[] data = CropPicture(imageData, 500, 500);
SqlConnection cn = new SqlConnection("Data Source=.;Initial Catalog=test;Integrated Security=True");
string qry = "insert into val (id,img) values (#OriginalPath, #ImageData)";
SqlCommand SqlCom = new SqlCommand(qry, cn);
SqlCom.Parameters.Add(new SqlParameter("#OriginalPath",(object)"123"));
SqlCom.Parameters.Add(new SqlParameter("#ImageData", (object)data));
cn.Open();
SqlCom.ExecuteNonQuery();
}
byte[] ReadFile(string sPath)
{
byte[] data = null;
FileInfo fInfo = new FileInfo(sPath);
long numBytes = fInfo.Length;
FileStream fStream = new FileStream(sPath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fStream);
data = br.ReadBytes((int)numBytes);
return data;
}
public static byte[] CropPicture(byte[] imgFile, int targetW, int targetH)
{
Image imgPhoto = Image.FromStream(new MemoryStream(imgFile));
int targetX = (imgPhoto.Width - targetW) / 2;
int targetY = (imgPhoto.Height - targetH) / 2;
Bitmap bmpPhoto = new Bitmap(targetW, targetH, PixelFormat.Format24bppRgb);
bmpPhoto.SetResolution(80, 60);
Graphics gfxPhoto = Graphics.FromImage(bmpPhoto);
gfxPhoto.SmoothingMode = SmoothingMode.AntiAlias;
gfxPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfxPhoto.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfxPhoto.DrawImage(imgPhoto, new Rectangle(0, 0, targetW, targetH), targetX, targetY, targetW, targetH, GraphicsUnit.Pixel);
MemoryStream mm = new MemoryStream();
bmpPhoto.Save(mm, System.Drawing.Imaging.ImageFormat.Jpeg);
// Dispose of all the objects to prevent memory leaks
imgPhoto.Dispose();
bmpPhoto.Dispose();
gfxPhoto.Dispose();
return mm.GetBuffer();
}
then insert it in the sql database
i got a code to crop the image.and i know how to insert image into sql database
but it all need to read the image as a file in the pc.
i stream the image then save it
then get it and crop it and insert it into db
PLEASE can any one tell me how to get the stream without the need to save it
You should be able to use something like this... (not tested)
Image img = Image.FromStream((new WebClient()).OpenRead("a"));

Saving and retrieving image in SQL database from C# problem

I used this code for inserting records in a person table in my DB
System.IO.MemoryStream ms = new System.IO.MemoryStream();
Image img = Image_Box.Image;
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
this.personTableAdapter1.Insert(NIC_Box.Text.Trim(), Application_Box.Text.Trim(), Name_Box.Text.Trim(), Father_Name_Box.Text.Trim(), DOB_TimePicker.Value.Date, Address_Box.Text.Trim(), City_Box.Text.Trim(), Country_Box.Text.Trim(), ms.GetBuffer());
but when i retrieve this with this code
byte[] image = (byte[])Person_On_Application.Rows[0][8];
MemoryStream Stream = new MemoryStream();
Stream.Write(image, 0, image.Length);
Bitmap Display_Picture = new Bitmap(Stream);
Image_Box.Image = Display_Picture;
it works perfectly fine but if i update this with my own generated Query like
System.IO.MemoryStream ms = new System.IO.MemoryStream();
Image img = Image_Box.Image;
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
Query = "UPDATE Person SET Person_Image ='"+ms.GetBuffer()+"' WHERE (Person_NIC = '"+NIC_Box.Text.Trim()+"')";
the next time i use the same code for retrieving the image and displaying it as used above . Program throws an exception
alt text http://www.freeimagehosting.net/image.php?3bb5f0d4b3.jpg][img]http://www.freeimagehosting.net/uploads/th.3bb5f0d4b3.jpg
So can any one tell me why i can't figure it out.
Query = "UPDATE Person SET Person_Image =#pic WHERE (Person_NIC = '" + NIC_Box.Text.Trim() + "')";
SqlCommand cmd = new SqlCommand(Query);
SqlParameter picparameter = new SqlParameter();
picparameter.SqlDbType = SqlDbType.Image;
picparameter.ParameterName = "pic";
picparameter.Value = ms.GetBuffer();
cmd.Parameters.Add(picparameter);
db.ExecuteSQL(Query);
This thing worked with this code hurray lolz

Categories

Resources