Displaying image retrieved from database to image control

18,599

You have some decent general ideas, but the overall structure is lacking. Your best bet is to use a use a handler, but reference the handler in your success function. Example:

var userId = 'MyUserIdFromSomewhere';
$.ajaxFileUpload
(
    {
        url: 'AjaxFileUploader.ashx',
        secureuri: false,
        fileElementId: 'uploadControl',
        dataType: 'json',
        data: '{}',
        success: function () {
            $('.ImageId').attr('src', '/ImageRetrieval.ashx?user=' + userId);
        },
        error: function () {

        }
    }
)

You may want to modify your handler to look more like:

using System;
using System.Web;
using System.Configuration;
using System.IO;
using System.Data;
using System.Data.SqlClient;

public class DisplayImg : IHttpHandler
{

    public void ProcessRequest(HttpContext context)
    {
        Int32 userId;
        if (context.Request.QueryString["userId"] != null)
            userId = Convert.ToInt32(context.Request.QueryString["userId"]);
        else
            throw new ArgumentException("No parameter specified");

        context.Response.ContentType = "image/jpeg";
        Stream strm = getImage(userId);
        byte[] buffer = new byte[2048];
        int byteSeq = strm.Read(buffer, 0, 2048);
        //Test File output. IIS_USR *SHOULD* have write access to this path, but if not you may have to grant it
        FileStream fso = new FileStream( Path.Combine(Request.PhysicalApplicationPath, "test.jpg"), FileMode.Create);

        while (byteSeq > 0)
        {
            fso.Write(buffer, 0, byteSeq);
            context.Response.OutputStream.Write(buffer, 0, byteSeq);
            byteSeq = strm.Read(buffer, 0, 2048);
        }

        fso.Close();
    }

    public Stream getImage(string userid)
    {

        using (SqlConnection cn = MySqlDataAccess.sqlDataAccess.MySqlConnection())
        {
            using (SqlCommand cmd = MySqlDataAccess.sqlDataAccess.MySqlCommand(cn, CommandType.Text, "SELECT UserImage FROM Images WHERE UserId = @userid"))
            {
                cmd.Parameters.Add("@userid", SqlDbType.NVarChar).Value = userid;

                object theImg = cmd.ExecuteScalar();

                try
                {
                    return new MemoryStream((byte[])theImg);
                }
                catch
                {
                    return null;
                }
            }
        }
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

It's possible that the DataAdapter is encoding/interpreting the data blob incorrectly and corrupting your image.

Share:
18,599
Luke Villanueva
Author by

Luke Villanueva

....

Updated on June 04, 2022

Comments

  • Luke Villanueva
    Luke Villanueva almost 2 years

    I need help in displaying an image from database. I've read that it's efficient to use handlers to load image from database to a handler. But I don't want to use handlers because I assumed that when you set the imageUrl to a handler, the image will only be loaded upon pageLoad. In my case, I have a existing image present at my img tag, then after uploading, I need to change that image. I used ajaxFileUploader plugin and successfully uploaded and save the image to the database. My problem now is retrieving it.

    upon successful jquery ajax call, I will be calling a webmethod using ajax. Here is my code for that:

    $.ajaxFileUpload
    (
        {
            url: 'AjaxFileUploader.ashx',
            secureuri: false,
            fileElementId: 'uploadControl',
            dataType: 'json',
            data: '{}',
            success: function () {
                $.ajax({
    
                    type: "POST",
    
                    url: "UserProfile.aspx/displayImage",
    
                    data: jsonData,
    
                    contentType: "application/json; charset=utf-8",
    
                    dataType: "json",
    
                    success: function (mydata) {
                    }
                });
            },
            error: function () {
    
            }
        }
    )
    

    In my ImageRetrieval, the following codes are present:

        public void ProcessRequest(HttpContext context)
        {
        string userid = context.Request.QueryString["user"];
            DBAccess dbacc = new DBAccess();
            DataTable dt = dbacc.getImage(userid);
            byte[] image = ((byte[])dt.Rows[0]["UserImage"]);
            System.Drawing.Image img = byteArrayToImage(image);
    
            MemoryStream stream = new MemoryStream();
            img.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            img.Dispose();
            stream.Position = 0;
            byte[] data = new byte[stream.Length];
            stream.Read(data, 0, (int)stream.Length);
            stream.Dispose();
            context.Response.Clear();
            context.Response.ContentType = "image/jpeg";
            context.Response.BinaryWrite(data);
    }
    

    My Byte to Image conversion:

        public Image byteArrayToImage(byte[] byteArrayIn)
        {
            MemoryStream ms = new MemoryStream(byteArrayIn);
            Image returnImage = Image.FromStream(ms);
            return returnImage;
        }
    

    My database access:

        public DataTable getImage(string userid)
        {
            DataTable dtGetImage = new DataTable();
    
            using (SqlConnection cn = MySqlDataAccess.sqlDataAccess.MySqlConnection())
            {
                using (SqlCommand cmd = MySqlDataAccess.sqlDataAccess.MySqlCommand(cn, CommandType.Text, "SELECT * FROM Images WHERE UserId = @userid"))
                {
                    cmd.Parameters.Add("@userid", SqlDbType.NVarChar).Value = userid;
    
                    using (SqlDataAdapter da = MySqlDataAccess.sqlDataAccess.MySqlAdapter(cmd))
                    {
                        da.Fill(dtGetImage);
                    }
                }
            }
    
            return dtGetImage;
        }
    

    FileUploader.ashx code:

        public void ProcessRequest(HttpContext context)
        {
           string path = context.Server.MapPath("~/Temp");
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);
    
                var file = context.Request.Files[0];
    
                string userid = context.Request.QueryString["user"];
    
                string fileName;
    
                if (HttpContext.Current.Request.Browser.Browser.ToUpper() == "IE")
                {
                    string[] files = file.FileName.Split(new char[] { '\\' });
                    fileName = files[files.Length - 1];
                }
                else
                {
                    fileName = file.FileName;
                }
                string fileType = file.ContentType;
                string strFileName = fileName;
    
                int filelength = file.ContentLength;
                byte[] imagebytes = new byte[filelength];
                file.InputStream.Read(imagebytes, 0, filelength);
                DBAccess dbacc = new DBAccess();
                dbacc.saveImage(imagebytes, userid);
    
                var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                var result = new { name = file.FileName };
                context.Response.Write(serializer.Serialize(result));
        }
    

    Help please! Thanks!

  • Luke Villanueva
    Luke Villanueva almost 12 years
    Thanks for the tip. I clearly forgot the .attr. Another question, how can I access the userId from the url at the handler? Should I just use request querystring?
  • Jaime Torres
    Jaime Torres almost 12 years
    That would be the simplest approach assuming you aren't concerned about security/somebody accessing somebody else's images.
  • Luke Villanueva
    Luke Villanueva almost 12 years
    What if I'm concerned about the security? I think its time to take it to into consideration of having security.
  • Luke Villanueva
    Luke Villanueva almost 12 years
    @J Torres- Sir thank you again for the help. But the image is not displaying. There's a broken image sign I think it's either the conversion failed or the type issues. Can you help me with this?
  • Luke Villanueva
    Luke Villanueva almost 12 years
    public void ProcessRequest(HttpContext context) { string userId = HttpContext.Current.Request.QueryString["user"]; DBAccess dbacc = new DBAccess(); DataTable dt = dbacc.getImage(userId); context.Response.ContentType = "image/png"; context.Response.BinaryWrite((byte[])dt.Rows[0]["UserImage"]‌​); }
  • Jaime Torres
    Jaime Torres almost 12 years
    And just to be 100% certain, you have stored a png binary stream in your database? What happens if you point your browser directly at your handler with the appropriate query string? Will an image show up? If not, if you save that file, will any image editor open the file?
  • Luke Villanueva
    Luke Villanueva almost 12 years
    Its a jpg image. I tried changing the content type into "image/jpg" still not working. A broken image icon shows up when I point my browser at my handler. I didn't get the third question. Are you asking if I can open the image? If yes, yes I can open them.
  • Jaime Torres
    Jaime Torres almost 12 years
    When you are opening the image, are you opening the downloaded file from the handler, or the initial file in the database? Also, you should set the content type to "image/jpeg" not "image/jpg". Using tamper-data to look at a request/response for a real image versus the request for your handler will help you narrow the gap.
  • Luke Villanueva
    Luke Villanueva almost 12 years
    I edited my post. I included my database access where I retrieve the Images and place it to a datatable. I don't really know if you consider that opening the file or just plain retrieving. Thanks for the effort @J Torres.