Handler.ashx
public void ProcessRequest (HttpContext context)
{
string imageid = context.Request.QueryString["ImID"];
SqlConnection connection = new SqlConnection(con);
connection.Open();
SqlCommand command = new SqlCommand("SELECT PhotoStoreTB.Data FROM PhotoStoreTB INNER JOIN UserTB ON UserTB.UserID = PhotoStoreTB.UserID WHERE PhotoStoreTB.UserID ='" + imageid + "'", connection);
SqlDataReader dr = command.ExecuteReader();
dr.Read();
byte[] imagedata = (byte[])dr[0];
context.Response.ContentType = "image";
using (System.IO.MemoryStream str = new System.IO.MemoryStream(imagedata, true))
{
str.Write(imagedata, 0, imagedata.Length);
Byte[] bytes = str.ToArray();
context.Response.BinaryWrite(bytes);
}
connection.Close();
context.Response.End();
}
Exception Thrown from context.Response.End();
{Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack.}
Aspx Code
<asp:Image ID="Image2" runat="server" ImageUrl='<%#"Handler.ashx?ImID="+ Eval("PUserID")%>'
Height="115px" Width="115px" CssClass="img-border"/>
I want to display multiple images in data list
Data List Bind
try
{
ld.Openconnection();
SqlCommand Cmd = new SqlCommand("PGetPropertyByCriteria", ld.con);
Cmd.Parameters.AddWithValue("#StartIndex", 1);
Cmd.Parameters.AddWithValue("#EndIndex", 10);
Cmd.Parameters.AddWithValue("#flag", "Get");
Cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter SqlAda = new SqlDataAdapter(Cmd);
DataSet DsStudentDetails = new DataSet();
SqlAda.Fill(DsStudentDetails);
if (DsStudentDetails.Tables.Count > 0 && DsStudentDetails.Tables[0].Rows.Count > 0)
{
TotalPage = (Int32.Parse(DsStudentDetails.Tables[0].Rows[0]["row"].ToString()) / PageSize) + ((Int32.Parse(DsStudentDetails.Tables[0].Rows[0]["row"].ToString()) % PageSize) > 0 ? 1 : 0);
CurrentRecord = DsStudentDetails.Tables[0].Rows.Count;
DataTable tDataTable = new DataTable("PagingTable");
tDataTable.Columns.Add(new DataColumn("LinkButtonVisible", typeof(bool)));
tDataTable.Columns.Add(new DataColumn("DisplayName", typeof(string)));
tDataTable.Columns.Add(new DataColumn("Value", typeof(string)));
tDataTable.Columns.Add(new DataColumn("LabelVisible", typeof(bool)));
dtlProduct.DataSource = DsStudentDetails.Tables[0];
dtlProduct.DataBind();
}
else
{
DLPAGING.DataSource = null;
DLPAGING.DataBind();
dtlProduct.DataSource = null;
dtlProduct.DataBind();
}
}
catch (Exception ex)
{
ex.ToString();
}
finally
{
ld.Closeconnection();
}
Please Help me to display multiple images to datalist from database
Try using Response.Clear(); at the begining of ProcessRequest function.
Or
you can use ApplicationInstance.CompleteRequest instead of Response.Clear();
Change your response content type from
context.Response.ContentType = "image";
To
context.Response.ContentType = "image/jpeg(png)"; depends on type
and remove context.Response.End()
Just see the below sample code
byte[] image = imagefromDB();
context.Response.OutputStream.Write(image, 0, image.Length);
context.Response.ContentType ="image-mime-type";
I can't assure Response.CLear(); is a good idea though. Sometimes it gets glitchy. I know, I've tried.
try using jpg with the image response instead of jpeg. Sometimes it doesn't work either. jpg works all the time.
When you use a Handler, each instance of where the handler is called has its own Response object. Therefore you can bind the dynamic paths of the images from the server code.
using a GridView and binding the RowDataBound event you can do this quite easily.
protected void gvAlbumImages_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DataRow aRow = ((DataRowView)e.Row.DataItem).Row;
//This is the Row from your Datasource (which is a datatable)
Image img = (Image)e.Row[e.Row.RowIndex].FindControl("imgControl");
//get the Image object at the row you are binding to.
//now simply set the source from the value in the DataRow
img.ImageUrl = string.format("~/ImageHandler.ashx?ImageID={0}",aRow.Field<int>("ImageID")
}
}
Related
I am new to ASP & C# and have been unable to figure out how to do this.
I am loading BLOB's from a bd via an .ashx file like so <img src="getimage.ashx" /> and it works fine, but sometimes there is no BLOB or it is empty.
here is the basic code
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["DataSource.iMIS.Connection"].ConnectionString);
SqlCommand cmd = new SqlCommand("SELECT PICTURE_LOGO FROM Name_Picture WHERE ID = #EmpID", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.Add("#EmpID", id);
con.Open();
byte[] pict = (byte[])cmd.ExecuteScalar();
con.Close();
ctx.Response.ContentType = "image/bmp";
ctx.Response.OutputStream.Write(pict, 0, pict.Length);
My thought is to check pict.Length right after con.Close() and if it fails, I want to display a default image, or even text.
Is that possible? How?
If you want to load an image from the disk when none is found in the DB, use this snippet.
public void ProcessRequest(HttpContext context)
{
//create a new byte array
byte[] pict = new byte[0];
//create a connection to the db and a command
using (SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["DataSource.iMIS.Connection"].ConnectionString))
using (SqlCommand command = new SqlCommand("SELECT PICTURE_LOGO FROM Name_Picture WHERE ID = #EmpID", connection))
{
//set the proper command type
command.CommandType = CommandType.Text;
//replace the parameters
command.Parameters.Add("#EmpID", SqlDbType.Int).Value = id;
try
{
//open the db and execute the sql string
connection.Open();
pict = (byte[])command.ExecuteScalar();
}
catch (Exception ex)
{
//catch any errors like unable to open db or errors in command. view with ex.Message
}
}
//if no image found in database load the default from disk
if (pict == null || pict.Length == 0)
{
pict = File.ReadAllBytes(context.Server.MapPath("/noimage.bmp"));
}
//clear the buffer stream
context.Response.ClearHeaders();
context.Response.Clear();
context.Response.Buffer = true;
//set the correct ContentType
context.Response.ContentType = "image/bmp";
//set the filename for the image
context.Response.AddHeader("Content-Disposition", "attachment; filename=\"ImageName.bmp\"");
//set the correct length of the string being send
context.Response.AddHeader("content-Length", pict.Length.ToString());
//send the byte array to the browser
context.Response.OutputStream.Write(pict, 0, pict.Length);
//cleanup
context.Response.Flush();
context.ApplicationInstance.CompleteRequest();
}
After a lot more searching and a lot of 'HttpCompileException(s)' I got this working.
Thanks to #Kazar for this answer here https://stackoverflow.com/a/2070493/3790921 and #Pranay Rana for this answer here https://stackoverflow.com/a/3801289/3790921
I put this together...
con.Open();
byte[] pict = (byte[])cmd.ExecuteScalar();
con.Close();
ctx.Response.ContentType = "image/bmp";
if (pict.Length <= 1) {
// the BLOB is not a picture
byte[] txt = ImageToByteArray(DrawText("no image found"));
ctx.Response.OutputStream.Write(txt, 0, txt.Length);
} else {
// stream the picture data from BLOB
ctx.Response.OutputStream.Write(pict, 0, pict.Length);
}
and it is working.
I am really new to C#, so I have a lot of problems. I have a Windows Form with a SQL Database and I want to see the picture that I have saved with the rest of the data in the PictureBox and TextBoxes when I select for example user 1 in the DataGridVie. I know what my problem is but not how to fix it.
void Load_table()
{
try
{
string myConnectionstring = "datasource=localhost;port=3306; username=root;password=root";
MySqlConnection myConnection = new MySqlConnection(myConnectionstring);
MySqlCommand myCommand = new MySqlCommand("SELECT idBenutzerdaten, name, vorname, straße, hausnr, plz, wohnort, telenr, personr, schlossnr, picture FROM testdb.benutzerdaten;", myConnection);
MySqlDataAdapter myDataAdapter = new MySqlDataAdapter();
myDataAdapter.SelectCommand = myCommand;
myDataTable = new DataTable();
myDataAdapter.Fill(myDataTable);
BindingSource mySource = new BindingSource();
mySource.DataSource = myDataTable;
dataGridView.DataSource = mySource;
myDataAdapter.Update(myDataTable);
}
catch (Exception fehler)
{
MessageBox.Show("Es gibt ein Problem mit der Datenbank\n" + fehler.Message, "Datenbankfehler ", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
This is the code to get the Data from the Database to the DataGridView. When I want to get the saved image as well, I get an error. I know that I have to change the column to an image column or something like that, but nothing I found so far worked out for me.
private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
panel.Enabled = false;
DataGridViewCell cell = null;
foreach (DataGridViewCell selectedCell in dataGridView.SelectedCells)
{
cell = selectedCell;
break;
}
if (cell != null)
{
DataGridViewRow row = cell.OwningRow;
tbx_id.Text = row.Cells[0].Value.ToString();
tbx_name.Text = row.Cells[1].Value.ToString();
tbx_vorname.Text = row.Cells[2].Value.ToString();
tbx_strasse.Text = row.Cells[3].Value.ToString();
tbx_hausnr.Text = row.Cells[4].Value.ToString();
tbx_plz.Text = row.Cells[5].Value.ToString();
tbx_wohnort.Text = row.Cells[6].Value.ToString();
tbx_telenr.Text = row.Cells[7].Value.ToString();
tbx_perso.Text = row.Cells[8].Value.ToString();
tbx_schlossnr.Text = row.Cells[9].Value.ToString();
}
}
The event from the datagridview. Not sure what and how to add here. But must be something like
imagebox.image = row.Cell[10].Value.Image();
I guess the problem is that the rows of the datagridview come 1 to 1 from the database, and I should create them manually, but then I got even more errors.
Any help will be appreciated. Thanks.
Are you using blob to store the images? just cast it
imagebox.image = byteArrayToImage(row.Cell[10].Value));
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
I believe Your Problem is that you are not casting to get the propertype
try this :
imagebox.image = ((DataGridViewImageColumn)row.Cell[10]).Image();
// or try this :
imagebox.image = (Image)row.Cell[10].Value;
if you don't have any other problem with your code those should work with you
I have a question- How to display image in browser without saving image in Temp folder? Is it even possible? My code have to reading images from database and displaying images in website. I actually try with converting data from database and I don't know what I want to do.
I try also with "imageHandlers", "FileStream", "Base64StringToBitmap" and nothing still works...
Please write example code or modify my code.
private void LoadImages()
{
ImageButton imageButton = new ImageButton();
string constr = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;
using (SqlConnection conn = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "select Id, Name, Data from tblFiles WHERE email = #CurrentUser";
cmd.Parameters.Add("#CurrentUser", SqlDbType.NVarChar);
cmd.Parameters["#CurrentUser"].Value = User.Identity.Name;
cmd.Connection = conn;
conn.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
if (sdr.HasRows)
{
sdr.Read();
string fileName = sdr["Name"].ToString();
FileInfo fi = new FileInfo(fileName);
byte[] byte_image_string = ((byte[])sdr["Data"]);
string image_string = Convert.ToBase64String((byte[])sdr["Data"]) + fi.Name;
imageButton.Height = Unit.Pixel(100);
imageButton.Style.Add("padding", "5px");
imageButton.Width = Unit.Pixel(100);
imageButton.Click += new ImageClickEventHandler(imageButton_Click);
Panel1.Controls.Add(imageButton);
System.Drawing.Image newImage;
if (byte_image_string != null)
{
using (MemoryStream stream = new MemoryStream(byte_image_string))
{
newImage = System.Drawing.Image.FromStream(stream);
//I want here display image to browser without saving
//string newPhoto = "";
//newImage.Save(newPhoto);
imageButton.ImageUrl = "data:image/jpg;base64," + newPhoto;
}
}
conn.Close();
}
}
}
}
}
My example image code from database:
0xFFD8FFE000104A46494600010100000100010000FFE1018C45786966000049492A0008000000020031010200070000002600000069870400010000002E00000000000000476F6F676C6500000500009007000400000030323230099007000B0000007000000086920700080100007B00000002A00400010000006F02000003A0
This is how I do it in one of my projects: Look src part
<p><a href='<%#"TheObject.aspx?O=" + Eval("ID") %>'><img runat="server" visible='<%#Eval("AttachmentID") != DBNull.Value %>' class="objPicture1" alt='<%Eval("Title") %>' width="340" height="260" src='<%#"~/Attachment.aspx?ID=" + Eval("AttachmentID")%>' /></a></p>
In Attachment.aspx you have this code:
protected void Page_Load(object sender, EventArgs e)
{
Guid objID = //take the ID of the object ?ID=""
DataRow attachmentRow = //fetch DataRow of the Attachment from Database
if (attachmentRow == null)
return;
Response.ContentType = attachmentRow["ContentType"].ToString();// value of this is image/gif or image/jpeg and etc.
Response.BinaryWrite((byte[])attachmentRow["Data"]); // Data is type image in my case
Response.End();
}
It looks like you are creating Base64String in wrong way. You are appending file name to it that should not work. just try following.
string image_string = Convert.ToBase64String((byte[])sdr["Data"]);
Assign directly it to ImageUrl. no need to use MemoryStream here.
imageButton.ImageUrl = "data:image/jpg;base64," + image_string;
I have created a table in which there is one column of type varbinary(max) to store the files.
What I want to do is that I want to show a pictureBox if that column is not null nad I have written this code:
private void ViewSentMailDet_Load(object sender, EventArgs e)
{
picturebox.Visible = false;
string con_string = #"Data Source=(local);Initial Catalog=fyp;Integrated Security=true";
SqlConnection con = new SqlConnection(con_string);
string qry = "select file from sentmail where msg_id='"+id of a particular row+"'";
SqlDataAdapter ad = new SqlDataAdapter(qry, con);
DataTable dt = new DataTable();
ad.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
if (dr["file"] != null)
picturebox.Visible = true;
}
}
But still its showing the pictureBox on load event of this page even if the file column is null.
Furthermore I want to download this particular file from the table to a disc when the user clicks on the pictureBox.
One of the major rules of using any kind of database is never return data you don't need. With this in mind you should exclude rows with no image using the query rather than checking after the fact.
So:
"select file from sentmail where msg_id='"+id of a particular row+"' and file is not null"
Rather than:
if (dr["file"] != DBNull.Value)
{
picturebox.Visible = true;
}
Giving us:
private void ViewSentMailDet_Load(object sender, EventArgs e)
{
picturebox.Visible = false;
string con_string = #"Data Source=(local);Initial Catalog=fyp;Integrated Security=true";
SqlConnection con = new SqlConnection(con_string);
string qry = "select file from sentmail where msg_id='"+id of a particular row+"' and file is not null";
SqlDataAdapter ad = new SqlDataAdapter(qry, con);
DataTable dt = new DataTable();
ad.Fill(dt);
foreach (DataRow dr in dt.Rows)
{
using (var ms = new MemoryStream((byte[])dr["file"]))
picturebox.Image = Image.FromStream(ms);
picturebox.Visible = true;
}
}
if (dr["file"] != DBNull.Value)
{
picturebox.Visible = true;
}
To check if the column contains binary data or null, you can use
if(!dr.IsNull("attach"))
{
attachment.Visible = true;
}
Get image bytes
Byte[] bytes = (Byte[])dr["attach"];
Convert image bytes to image
Image image = null;
using (var ms = new MemoryStream(bytes))
image = Image.FromStream(ms);
Show the picture on the picturebox
picturebox.Image = image;
To save the image, on picturebox.Click event handler
picturebox.Image.Save(#"drive:/path/to/save/image.bmp");
Glad to help! Please remember to accept the answer if you found it helpful.
My project allow admin to add medal for officer profile, currently I only able to insert the maximum of 5 medals. But my teacher ask me to let the admin insert as many medal as they want for the officer profile. I not sure how do I retrieve all the image that the admin inserted, I know how to insert image into database using varbinary. Do give me way for doing this. THANKS!
Code Below is how I do for inserting at maximum of 5 medals:
Code for uploading:
System.Drawing.Image uploaded = System.Drawing.Image.FromStream(FileUpload1.PostedFile.InputStream);
System.Drawing.Image newImage = new Bitmap(1024, 768);
using (Graphics g = Graphics.FromImage(newImage))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(uploaded, 0, 0, 1024, 768);
}
byte[] results;
using (MemoryStream ms = new MemoryStream())
{
ImageCodecInfo codec = ImageCodecInfo.GetImageEncoders().FirstOrDefault(c => c.FormatID == ImageFormat.Jpeg.Guid);
EncoderParameters jpegParms = new EncoderParameters(1);
jpegParms.Param[0] = new EncoderParameter(Encoder.Quality, 95L);
newImage.Save(ms, codec, jpegParms);
results = ms.ToArray();
}
string sqlImage = "Insert into OfficerMedal(policeid, image) values ('" + Session["policeid"] + "', #Data)";
SqlCommand cmdImage = new SqlCommand(sqlImage);
cmdImage.Parameters.AddWithValue("#Data", results);
InsertUpdateData(cmdImage);
I retrieve image using aspx page
protected void Page_Load(object sender, EventArgs e)
{
string strQuery = "select image from OfficerMedal where policeid='" + Session["policeid"] + "'";
SqlCommand cmd = new SqlCommand(strQuery);
DataTable dt = GetData(cmd);
if (dt != null)
{
download(dt);
}
}
private DataTable GetData(SqlCommand cmd)
{
DataTable dt = new DataTable();
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
SqlDataAdapter sda = new SqlDataAdapter();
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
try
{
con.Open();
sda.SelectCommand = cmd;
sda.Fill(dt);
return dt;
}
catch
{
return null;
}
finally
{
con.Close();
sda.Dispose();
con.Dispose();
}
}
private void download(DataTable dt)
{
// check if you have any rows at all
// no rows -> no data to convert!
if (dt.Rows.Count <= 0)
return;
// check if your row #0 even contains data -> if not, you can't do anything!
if (dt.Rows[0].IsNull("image"))
return;
Byte[] bytes = (Byte[])dt.Rows[0]["image"];
Response.Buffer = true;
Response.Charset = "";
Response.Cache.SetCacheability(HttpCacheability.NoCache);
Response.ContentType = "image/jpg";
Response.BinaryWrite(bytes);
Response.End();
}
To add on for this current method I retrieving image 1 by 1 from database. Instead of retrieving all image that belong to the officer.
The usual way to do this is with a HttpHandler rather than in your ASPX page itself. The handler is responsible for retrieving the image data from your database and outputting it as a graphic; it can then be used as the src for a regular <img> tag or the ImageUrl property for an <asp:image> control.
The easiest way to add a handler is to select Generic Handler in the Add New Item dialog:
In the code for the handler, ProcessRequest is the method that does the work e.g.
public void ProcessRequest(HttpContext context)
{
byte[] imageBytes;
// Get the id of the image we want to show
string imageId = context.Request.QueryString["ImageId"];
// Get the image bytes out of the database
using (SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
// Pass in the image id we got from the querystring
SqlCommand cmd = new SqlCommand("SELECT image FROM PoliceMedal WHERE ImageId=" + imageId, conn);
conn.Open();
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
reader.GetBytes(0, 0, imageBytes, 0, int.MaxValue);
}
context.Response.Buffer = true;
context.Response.Charset = "";
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.ContentType = "image/jpg";
context.Response.BinaryWrite(imageBytes);
context.Response.End();
}
So we have our handler that will return the image data from the database, and we call this with a url like \ImageHandler.ashx?ImageId=1. This does require a change to your database in that you'll need to add a key to the PoliceMedal table - I suggest a SQL Server IDENTITY column.
It's not clear from your question how you're displaying the images on the ASPX page, so here I'll just show you how to add them into a PlaceHolder. So, we'll retrieve the set of image ids for an officer, construct an <asp:image> control for each of them and add the images to the PlaceHolder.
protected void Page_Load(object sender, EventArgs e)
{
using (
SqlConnection conn =
new SqlConnection(WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
// Query the table to get the list of image IDs for the current user
SqlCommand cmd = new SqlCommand("SELECT ImageId FROM PoliceMedal WHERE policeid = " + Session["policeid"], conn);
conn.Open();
SqlDataReader imageReader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
// For each image in the database
while (imageReader.Read())
{
// Create the new Image control
Image medalImage = new Image();
// Call the handler, passing the id of the image in the querystring
medalImage.ImageUrl = string.Format("ImageHandler.ashx?ImageId={0}",
imageReader.GetInt32(0));
// Add the image to the placeholder
MedalPlaceHolder.Controls.Add(medalImage);
}
}
}