Retrieving image from database not showing up on page - c#

I have been able to upload an image to sql server, in binary format. This is the code that I am using to upload it..
protected void Button2_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
string filename = FileUpload1.FileName;
Stream imgStream = FileUpload1.PostedFile.InputStream;
int imgLen = FileUpload1.PostedFile.ContentLength;
byte[] imgBinaryData = new byte[imgLen];
string strCm = "s_PictInsert";
SqlCommand cm = new SqlCommand(strCm, Cn);
cm.CommandType = CommandType.StoredProcedure;
cm.Parameters.Add(new SqlParameter("#TheImage", SqlDbType.Image)).Value = imgBinaryData;
Cn.Open();
cm.ExecuteNonQuery();
Cn.Close();
}
}
When I look at the database, all I see in the database, of the pic I uploaded, is 0x00000000000000 etc...I don't know why it looks like that...
Then I am using this code to retrieve the image..
protected void Button3_Click(object sender, EventArgs e)
{
string strCm = "select TheImage from [Pictures] where PictureID = 2";
SqlCommand cm = new SqlCommand(strCm, Cn);
cm.CommandType = CommandType.Text;
Cn.Open();
SqlDataReader dr = cm.ExecuteReader();
if (dr.Read())
{
Response.ContentType = "image/jpg";
Response.BinaryWrite((byte[])dr["TheImage"]);
}
Cn.Close();
}
when I click the button it doesn't show me the image it just writes the markup out to the page.
What I want to do is retrieve the image and put it to an asp image, the thing is the images that I upload can be .png format.
I only used response.binarywrite is because that is what I was shown to do. But it doesn't work the way I was told it would.
Thanks

The problem is with your upload function, you are not setting imgBinaryData with the data from the file stream, you are only settings the size to match, so it will default to all zeros.
Instead of this part:
byte[] imgBinaryData = new byte[imgLen];
Replace it with this:
byte[] imgBinaryData = null;
using (var reader = new BinaryReader(FileUpload1.PostedFile.InputStream))
{
imgBinaryData = reader.ReadBytes(FileUpload1.PostedFile.ContentLength);
}
Then check to see what your database data looks like.
On a side note, I would recommend always storing file name and MIME type when storing files in a database, you never know when you will need them!

try this:
var length = FileUpload1.PostedFile.ContentLength;
Byte[] imgBinaryData = new Byte[length];
var stream = FileUpload1.FileContent;
stream.Read(imgBinaryData, 0, length);
then insert the binary object. Your code does not read the image into the stream for insertion. The above code should read the image into the byte array, then your db code should insert actual data instead of the placeholder.

You are storing image in binary format to the database, you will retrieve the same. You need to use MemoryStream to get the image from the byte array that you retrieved.
See this :
Retrieve image from database and display on ASP.NET without httphandler

Related

I want to save image in jpg format from SQL Server database but when I download it , it has only 1KB size and cannot be opened

private void Msg1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
string SaveFileTo = "D:\\DA.jpg";
// string SaveFileTo = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// string filename = "jmk.jpg";
// SaveFileTo = Path.Combine(SaveFileTo, filename);
CN.Open();
SqlCommand cmd = new SqlCommand("select photo from edistindata where enrollno='" + CboEnroll.Text + "' ", CN);
DR = cmd.ExecuteReader();
byte[] data = null;
while (DR.Read())
{
data = (byte[])DR["Photo"];
}
using (var fs = new FileStream(SaveFileTo, FileMode.Create, FileAccess.Write))
{
fs.Write(data,0,data.Length);
}
MessageBox.Show("Success");
}
I have run the code in the question, even it has some of not good coding practices, if the data in the photo column is not corrupted it should produce the image file.
so I have put down your code with proper enhancements that will flag you early before saving corrupted data.
private void Msg1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
ImageCodecInfo theJpgCodecInfo = ImageCodecInfo.GetImageEncoders()
.FirstOrDefault(encoder => encoder.MimeType == "image/jpeg");
var myEncoder = Encoder.Quality;
var myEncoderPrams = new EncoderParameters(1);
myEncoderPrams.Param[0] = new EncoderParameter(myEncoder, 100L);
string SaveFileTo = "D:\\DA";
// string SaveFileTo = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
// string filename = "jmk.jpg";
// SaveFileTo = Path.Combine(SaveFileTo, filename);
CN.Open();
SqlCommand cmd = new SqlCommand("select photo from edistindata where
enrollno=#Enrol;", CN);
cmd.Parameters.AddWithValue("#Enrol", CboEnroll.SelectedItem.ToString());
DR = cmd.ExecuteReader();
byte[] data = null;
int idx = 0;
while (DR.Read())
{
data = (byte[])DR["Photo"];
Image tempImage;
try
{
tempImage = ByteArrayToImage(data);
}
catch (Exception exc)
{
MessageBox.Show(exc.GetType().ToString()
+Environment.NewLine+exc.Message);
continue;
}
var tempBitmap = new Bitmap(tempImage);
var tempFname = "D:\\DA"+(idx++).ToString()+".jpg";
tempBitmap.Save(tempFname, theJpgCodecInfo, myEncoderPrams);
}
}
public static Image ByteArrayToImage(byte[] byteArrayIn)
{
using (MemoryStream ms = new MemoryStream(byteArrayIn))
{
Image returnImage = Image.FromStream(ms);
return returnImage;
}
}
The enhancements that I suggested as follow:
As #derpirscher mentioned in his comment use parameters not string concatenation when building SQL commands and the easiest most lazy way to do it is Parameters.AddWithValue().
Use CboBox.SelectedItem.ToString in place of the .Text as been in your code.
instead of dumping the byte[] directly through a FileStream.Write() I transferred the byte array into Image() then into Bitmap().
this way if the byte[] (and hence the data in the db column photo) is not one of the binary formats the the class Image() can handle it will throw exception and I used that to show the related error.
Also, this way we over came some issues that may rise if we used Bitmap() directly if the data byte[] contains PNG format.
No matter what image format is stored in the photo column it will be legitimately re-encoded as Jpeg then saved.

Play video from blob data Oracle using C#

i have created simple project save blob file data into oracle database using c# winform and worked fine. Now, i wanna play video from blob oracle data using c# but i couldn't. here is my code:
if (koneksidb.con.State == ConnectionState.Open)
{
koneksidb.con.Close();
}
koneksidb.con.Open();
OracleCommand cmd = new OracleCommand();
OracleDataReader dr;
cmd.CommandText = #"SELECT ID,FILENAME, FILEDATA, KETERANGAN, SUBSTR(FILENAME, -4)AS FILEEXTENTION FROM LATIHANFILEMANAGER WHERE ID = '1' AND ISPREVIEW = N'1'";
cmd.Connection = koneksidb.con;
dr = cmd.ExecuteReader();
while (dr.Read())
{
string fileExtention = dr["FILEEXTENTION"].ToString(); //got file extention from database
switch(fileExtention)
{
case ".pdf": //when blob is pdf file worked fine
byte[] FileBytes = (byte[])dr["FILEDATA"];
System.IO.MemoryStream stream = new System.IO.MemoryStream(FileBytes);
fmPdfViewer f = new fmPdfViewer();
f.pdfViewer1.LoadDocument(stream); //when file .pdf i can display preview using pdf viewer in devexpress
f.Show();
break;
case ".mp4": //when blob is video
string path = ""; //here the problem how can i play file video from blob oracle data
fmVideoViewer vd = new fmVideoViewer();
vd.axWindowsMediaPlayer1.URL = path;
vd.axWindowsMediaPlayer1.settings.autoStart = true;
vd.Show();
break;
}
}
dr.Close();
really need the solution, thanks before.
You can save the file on disk and play it.
byte[] bytes = (byte[])dr["FILEDATA"];
string name = (string)dr["FILENAME"] + (string)dr["FILEEXTENTION"];
var path = System.IO.Path.Combine(Application.StartupPath, name);
System.IO.File.WriteAllBytes(path , bytes);
this.axWindowsMediaPlayer1.URL = path;
this.axWindowsMediaPlayer1.Ctlcontrols.play();
You can use Application.StartupPath or any other path you prefer to cache files.
After a while it's better to cleanup cached files.

How to save an image into a database?

I am using WPF to insert an image to my MySQL database. I can upload the file to image control but I don't know how to save it.
Here is what I've done so far. The emp_image is the image control that displays the photo.
private void btn_save_image_click(object sender,...)
{
Mysqlconnection cn= new mysqlconnection(connectionstring);
byte[] imagedata;
imagedata=File.ReadAllBytes(emp_img); //..here is error,it says has invalid arguments..//
mysqlcommand= new mysqlcommand("insert into dep_table(photo)values(?data)",cn);
cmd.parameters.addwithvalue("?data", imagedata);
cn.open();
cmd.executeNonQuery();
cn.close();
}
you need to convert the image source to byte[] :
public static byte[] ImageToArray(BitmapSource image)
{
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return stream.ToArray();
}
}
Then, call the function:
imagedata = ImageToArray((BitmapSource)emp_img.Source);
Seems you are not passing the file path.
Please check File::ReadAllBytes Method
Should be something like
var imagedata=File.ReadAllBytes(filepath);

How to get Image data from SQL Server, Write To File, Save File to Disk using C#

I'm trying to get attachments (images, word documents, etc.) stored as an Image datatype from a SQL Server database. The attachments can be of any file type, but I'm just trying to get a .jpg to download successfully.
I'm able to save the file to my local drive, but it appears to be corrupting the file in the process.
What I'm trying to do:
Retrieve binary data of type IMAGE from SQL Server Database.
Create a file from the binary data.
Save the file to a local directory.
My CODE:
public void ProcessRequest()
{
//Get the ticket number from query string
_ticketNumber = context.Request.QueryString["ID"];
SqlConnection conn = new SqlConnection(_DBConn);
SqlCommand cmd = new SqlCommand();
string fileName = ""; //Holds the file name retrieved from DB
byte[] data; // Holds the IMAGE data from DB
using (conn)
{
using (cmd)
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = #"SELECT File_Name, Data FROM Tickets_All INNER JOIN Attachments ON Tickets_All.ID = Attachments.[Object_ID] WHERE Ticket = #Ticket";
cmd.Parameters.AddWithValue("#Ticket", _ticketNumber);
cmd.Connection = conn;
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
fileName = reader.GetString(0);
data = (byte[])reader["Data"];
if (data != null)
{
SaveData(fileName, data);
}
}
}
reader.Close();
}
}
protected bool SaveData(string FileName, byte[] Data)
{
string path = #"C:\Windows\temp\test.jpg";
try
{
BinaryWriter writer = new BinaryWriter(File.OpenWrite(path));
writer.Write(Data);
writer.Flush();
writer.Close();
}
catch (Exception ex)
{
return false;
}
return true;
}
Please forgive me if the code isn't up to par with best practices, I'm more of a VB programmer and I've never had to do this before. I'm just trying to get a working example.
Thanks in advance.
I would use the Image.FromStream method to do this :
http://msdn.microsoft.com/en-us/library/system.drawing.image.fromstream(v=vs.110).aspx
protected bool SaveData(string FileName, byte[] Data)
{
using (Image image = Image.FromStream(new MemoryStream(Data)))
{
image.Save("MyImage.jpg", ImageFormat.Jpeg);
}
return true;
}
Thanks for the input everyone. After doing some additional testing, I think that the data being retrieved from the database has been compressed in some way. I'm able to insert and pull out files programmatically just fine, the problem comes in when the application puts the data into the database (3rd party software). I'm going to look into the compression what I can come up with.

store a blob string in database table

Hi I'm new to azure storage blob. I have a project in WPF and I have created a container in azure storage blob that I can send /upload images to on button click. Can anyone tell me if I can store a string form the blob into my sql database that will allow me to access/use/display the image in my WPF project.
Maybe someone could direct me to an example! Thanks!
private void btnSAVE_Click(object sender, RoutedEventArgs e)
{
try
{
byte[] photo = GetPhoto(filePath);
sc.Open();
cmd = new SqlCommand("Insert into Rewards (Name, Picture, ) values'" + txtName.Text+ "','" + txtPicture.Text + "')", sc);
cmd.Parameters.Add("#Picture", SqlDbType.Image, photo.Length).Value = photo;
cmd.ExecuteNonQuery();
MessageBox.Show("Inserted");
sc.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
displayAll();
}
private byte[] GetPhoto(string filePath) {
{
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
byte[] photo = br.ReadBytes((int)fs.Length);
br.Close();
fs.Close();
return photo;
}
}
You can just store URL of that blob and use that URL to display image
CloudBlockBlob blockBlob = new CloudBlockBlob();
using (var fileStream = System.IO.File.OpenRead(path + "/" + up.GetName().ToString()))
{
blockBlob.UploadFromStream(fileStream);
}
string URL = blockBlob.Uri.OriginalString;
Refer to this link Writing BLOB values to a database.
From MSDN:
To write a BLOB value to your database, issue the appropriate INSERT
or UPDATE statement and pass the BLOB value as an input parameter. If
your BLOB is stored as text, such as a SQL Server text field, you can
pass the BLOB as a string parameter. If the BLOB is stored in binary
format, such as a SQL Server image field, you can pass an array of
type byte as a binary parameter.

Categories

Resources