I have created a web page where I have used Image control to display the image. Along with this control I have some labels and input box also
Below is the code which I have used to save the image to database
byte[] imageSize = new byte[FileUpload1.PostedFile.ContentLength];
HttpPostedFile uploadedImage = FileUpload1.PostedFile;
uploadedImage.InputStream.Read(imageSize, 0, (int)FileUpload1.PostedFile.ContentLength);
SqlParameter UploadedImage = new SqlParameter("#image", SqlDbType.Image, imageSize.Length);
UploadedImage.Value = imageSize;
string sql = "insert into imageDB(Image) values (#image)";
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.Add(UploadedImage);
cmd.ExecuteNonQuery();
}
and below is the code I have used to retrieve the image from database
byte[] rawImg = (byte[])rdr["image"];
MemoryStream Stream = new MemoryStream();
Stream.Write(rawImg, 0, rawImg.Length);
Bitmap Display_Picture = new Bitmap(Stream);
//after this no idea how to proceed
I have read some links all are suggesting we can not set this byte information to Image control.
Let me know if my way of retrieving the image from data base is right, if its right, what type of control I should use, so that image which has been retrieved from database can be displayed on web page
Is my way of retrieving the image from database right?
I would use the following code instead (sorry not tested):
byte[] imageBytes = Convert.FromBase64String(rdr["image"]);
MemoryStream stream = new MemoryStream(imageBytes);
Image image = Image.FromStream(stream);
How do I bind the image to an asp.net image control?
I would create an HttpHandler which gets and returns the image. Then bind the ImageUrl property on the asp:Image to the url of the HttpHandler.
How you can do this you can see in the answer of Dale Ragan over here: How to bind a MemoryStream to asp:image control?
First, in your example your have to reset the Position inside your stream to 0: Stream.Position = 0;
Second, you have to write your image to a local cache folder of your web service that is part of your web application. You image control can have a Source-reference (img.src) to the address of that image.
Or... you can create an AXD-file / HttpHandler. An AXD file is a file, just like an ASPX, but specialized in returning any type of data, like an image.
For more info, see: http://blog.kurtschindler.net/post/using-httphandlers-to-serve-image-files
To retrieve image, and show on asp.net Image control, you can
cn.Open();
SqlCommand cm = new SqlCommand("select * from ImageCollection where img_id='" + DropDownList1.SelectedItem.ToString() + "'", cn);
SqlDataAdapter da = new SqlDataAdapter(cm);
SqlDataReader dr = cm.ExecuteReader();
try
{
if (dr.Read())
{
string image1 = Convert.ToString(DateTime.Now.ToFileTime());
FileStream fs1 = new FileStream(image1, FileMode.CreateNew, FileAccess.Write);
byte[] bimage1 = (byte[])dr["passport_photo"];
fs1.Write(bimage1, 0, bimage1.Length - 1);
fs1.Flush();
Image1.ImageUrl = "~/images/"+DropDownList1.SelectedItem.ToString();
}
dr.Close();
cn.Close();
}
catch (Exception ex)
{
throw ex;
}
Alternative solution:
Implement a handler to serve the image. Have a look at the System.Web.IHttpHandler interface.
The idea would be to write an image tag in your page along the lines of:
<asp:image runat="server" imageurl="~/Image.ashx?ID=xxx" />
Then in your handler implementation, get the id from the querystring, retrieve the image as you're already doing and then write directly to the response stream.
Related
So I collect a varbinary(MAX) value from a database where an image is stored.
It gets converted to byte[], then the aim is to display this in an image control.
This is where I read from the database
public TemplateData(SqlDataReader dr)
{
initialiseData();
if (dr.HasRows)
{
Logo = (byte[])dr["Logo"];
//Logo = dr["Logo"].ToString();
TemplateId = dr["TemplateId"].ToString();
Comment = dr["Comment"].ToString();
SchemeCode = dr["SchemeCode"].ToString();
Version = dr["Version"].ToString();
}
}
This is where the values are displayed into the corresponding controls
protected void ddSchemeCode_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddSchemeCode.SelectedIndex > 0)
{
// Existing Data to load from database
TemplateData temp = DataClass.ReturnData(ddSchemeCode.SelectedItem.Text);
if (temp != null)
{
txtVersion.Text = temp.Version;
txtComment.Text = temp.Comment;
txtSchemeCode.Text = temp.SchemeCode;
txtTemplateId.Text = temp.TemplateId;
img.Src = temp.Logo;
}
So at the moment I am passing a byte[] into the source of an image control, where it would instead like a string. I've tried converting it to a string with Convert.ToBase64String(Logo) and ToString(Logo) but these do not work.
Any help is greatly appreciated. Cheers guys and gals.
Try converting the byte array to image and assign it to picturebox as below,
try
{
using (MemoryStream mStream = new MemoryStream())
{
// where pData is your byte array
mStream.Write(pData, 0, Convert.ToInt32(pData.Length));
Image originalImage = Image.FromStream(mStream);
picBox.Image = originalImage;
}
}
catch (Exception ex)
{
}
Hope it helps.
As you may have noticed, you cannot "print" an image in a webpage. You need to get a little bit creative now.
What you want to look into is Response.BinaryWrite. More information about that, here: https://msdn.microsoft.com/en-us/library/system.web.httpresponse.binarywrite%28v=vs.110%29.aspx
You will probably also need a generic ashx handler. Here is an example of how to show a picture using a handler: http://www.dotnetperls.com/ashx
My suggestion would be to store the logo as a byte[] into the http session. Put the source of the image to theHttpHandlerYourGonnaCreate.ashx. You can then binary write the byte[] you've stored into the session there.
Hope this helps!
As Michael shows here, you can convert the byte array to a Bitmap object with something like this:
Bitmap bitmap = null;
using (MemoryStream imageStream = new MemoryStream(imageData))
{
bitmap = new Bitmap(imageStream);
}
It isn't entirely clear what you're using for a control to show the image, but any control that can display an image should be able to take a Bitmap or Image object.
I want to retrieve an image from a SQL Server database and show in a Image tool.
I have this code
<asp:Image ID="Image1" runat="server" CssClass="style2" Height="166px" Width="488px" />
SqlConnection connect = null;
string connectstring = "Data Source=.\\SQLEXPRESS;Initial Catalog=teste;Integrated Security=true;pooling=false";
connect = new SqlConnection(connectstring);
connect.Open();
string Scmd = "SELECT id, imagem where id = 2";
SqlCommand cmd = new SqlCommand(Scmd, connect);
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
if (reader.HasRows)
{
Label1.Text = reader[0].ToString();
byte[] imagem = (byte[])(reader[1]);
MemoryStream ms = new MemoryStream(imagem);
Image1.ImageUrl = ms.FromStream(ms); //i tried this
}
But I can't do this:
Image1.ImageUrl = ms.FromStream(ms);
because I get an error.
Somebody please can help me? The only problem I have is show the image.
Please help, thanks.
You can generate base64string out of byte array and use that as inline image source.
Convert to base64string. Refer this.
byte[] imagem = (byte[])(reader[1]);
string base64String = Convert.ToBase64String(imagem) ;
Use this string as inline image like following. Refer this.
Image1.ImageUrl = String.Format("data:image/jpg;base64,{0}",base64String);
Assumption: image saved as jpg.
If this differs, then change line in step#2.
Disclaimer: Base64string as image is suitable for small sized image , but if we have bigger image, then the string produced will have large sized string. Advantage is , browser don't have to request multiple times for each image ( if you implemented this as image.src= "http://handler-to-image").
I have a PictureBox with an image and a delete button. The image is stored in a varbinary(MAX) format in the database. How do I delete it when the delete button is pressed?
I'm using this code to save an image into the database:
byte[] data;
using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
{
conn.Open();
Image img = pictureBox1.Image;
img.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
data = stream.ToArray();
cmd.CommandText = "insert into images values(#images)";
cmd.Parameters.AddWithValue("#images", data);
int res = cmd.ExecuteNonQuery();
MessageBox.Show("success");
}
I don't see why the following wouldn't work.
cmd.CommandText = "delete from images where ID = x";
Sending plain SQL like this is getting fairly outdated and can be down right dangerous when implemented with a UI improperly, you should strongly consider using LINQ
http://en.wikipedia.org/wiki/Language_Integrated_Query
this may be impossible, or rather, not very popular, but I was wondering how I'd go about creating a data file for images, that would actually compress them? Say I had 200MB total of image files, is there some system I can use to store them in a single file, that would compress them to a total size of like 150MB? (Just example numbers, ratios not important).
I know I can encode the images with Base64 and then store them in an SQLite database, but I read that storing images in their encoded forms actually resulted in a slightly larger size than the original image file itself.
I was also thinking of a ZIP file, but I wasn't sure if it could be used as a 'library' as such?
If something like this doesn't exist as a predefined class, could someone lead me on the right track?
This is a mock of what I'm sort of looking for:
class ImageLibrary {
//this is where the code would go for the library?
}
class MyProgram{
public MyProgram()
{
ImageLibrary library = new ImageLibrary();
library.Add(<Image object here, with an ID of sorts>);
library.Add(<Another image object here, also with an ID>);
Load += new FormLoadEventHandler(MyProgram_Load);
}
void MyProgram_Load(object sender, EventArgs e)
{
PictureBox.Image = library.Get(<image id here>);
}
}
I hope this is possible. Else, I'll just put up with a slightly larger file size and Base64 encode them. But, because I have, at the moment, almost 500 images I want to store, a kB saved is a kB earned. :) Also, please don't judge the quality of my code example, it's just a mock up and I wrote it off the cuff.
Cheers, and thankyou in advance.
If save your images as binary files will help this is a code I use to convert them to binary and then save into SQLite:
public byte[] ImageToByte(Image image, System.Drawing.Imaging.ImageFormat format){
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();
return imageBytes;
}
}
public Image ByteToImage(byte[] imageBytes)
{
// Convert byte[] to Image
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = new Bitmap(ms);
return image;
}
And then to save the binary:
void SaveImage(byte[] image){
string conStringDatosUsuarios = #" Data Source = \Program Files\GPS___CAM\Data\DatosUsuarios.s3db ";
SQLiteConnection con = new SQLiteConnection(conStringDatosUsuarios);
SQLiteCommand cmd = con.CreateCommand();
cmd.CommandText = String.Format("INSERT INTO Users (Foto) VALUES (#0);");
SQLiteParameter p = new SQLiteParameter("#0", System.Data.DbType.Binary);
p.Value = image;
cmd.Parameters.Add(p);
con.Open();
try
{
cmd.ExecuteNonQuery();
}
catch (Exception exc1)
{
MessageBox.Show(exc1.Message);
}
con.Close();
}
Hope it helps
EDIT As you asked, I'm updating with the load image code:
(to convert the byte to image you must use the ByteToImage function)
void LoadImage(string tag){
string query = "SELECT Foto FROM Users;";
string conString = #" conection to your database ";
SQLiteConnection con = new SQLiteConnection(conString);
SQLiteCommand cmd = new SQLiteCommand(query, con);
con.Open();
try
{
SQLiteDataReader rdr = cmd.ExecuteReader();
try
{
while (rdr.Read())
{
pictureBox1.Image = ByteToImage((System.Byte[])rdr[0]);
}
}
catch (Exception exc) { MessageBox.Show(exc.Message); }
}
catch (Exception ex) { MessageBox.Show(ex.Message); }
con.Close();
}
EDIT 2 Try this to see which type of data are you trying to load:
System.Type checkType = rdr[0].GetType();
pictureBox1.Image = ByteToImage((System.Byte[])rdr[0]);
add the first line in your code and put a breakpoint in that line. Check checkType's type. Probably it isn't binary. Let me know the result to help you.
Check out this article: http://msdn.microsoft.com/en-us/library/aa479502.aspx
I hope it helps. An idea for accessing files from a ZIP. It's not ready-to-use solution, but a nice concept explanation.
I have been trying to read a picture saved in Access DB as a OLE object in a PictureBox in a C# windows Application.
The code that does this is presented below:
string connString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Rajesh\SampleDB_2003.mdb;";
OleDbConnection oConn = new OleDbConnection(connString);
oConn.Open();
string commandString = "select * from employee where id = " + id + "";
OleDbCommand oCmd = new OleDbCommand(commandString, oConn);
OleDbDataReader oReader = oCmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (oReader.Read())
{
txtID.Text = ((int)oReader.GetValue(0)).ToString();
txtName.Text = (string)oReader.GetValue(1);
txtAge.Text = ((int)oReader.GetValue(2)).ToString();
txtType.Text = (string)oReader.GetValue(3);
byte[] imageBytes = (byte[])oReader.GetValue(4);
MemoryStream ms = new MemoryStream();
ms.Write(imageBytes, 0, imageBytes.Length);
Bitmap bmp = new Bitmap(ms);
pbPassport.Image = bmp;
}
When I execute the above code, an 'Parameter is not valid' exception is thrown at the line:
Bitmap bmp = new Bitmap(ms)
From the exception message, it is clear that 'ms' is in a format that is not recognisable. Any suggestion to get past this?
Unfortunately I have no good answer for you, but I can tell you that when I tried, I got the same results. Sometimes skipping the first 78 bytes of the byte array worked, sometimes it didn't.
This is because the OLE Object datatype stores some kind of header in the field, so that Access knows what type of OLE Object it is. I could not find a reliable way to work out exactly where this header stopped and real data started, but I also gave up, so good luck :)
Do a google search for AccessHdr. You'll find references to AccessHdr.cpp and AccessHdr.h. These will illustrate what is need to extract the streams without the header.
You can't read OLE objects so easily. In fact, it is bad practice to keep pictures as OLE objects in database.
It is preferred to have em as BLOB objects or path and filename at some storage. AccessImagine can handle both scenarios for MS Access and C#. You can download it here - http://access.bukrek.net
You can try:
pbPassport.Image = Image.FromStream(ms);
Your bytestream is corrupted somehow, becouse I tried the exact method of yours but filled the byte array with PNG data from a file instead.
I would suggest creating two streams, one from the database, and one from the file that was the source of the image in the database. Then compare them byte by byte. If there is even one byte of diffrence, the database image data is corrupt.