Link to home
Start Free TrialLog in
Avatar of Nate_LR
Nate_LR

asked on

Asp.net C# image editing (rotating with ImageMagick and writing to EXIF) application either works randomly or not at all

I'm building an Asp.net in C# image uploading/viewing/editing application to be used on an intranet. Images are uploaded and stored in a directory on a file server. The web application is working through IIS which is running on a computer (not a server) on our network. One of the aspx pages is an image gallery, where thumbnails are generated and the user can click a thumbnail to go to DisplayPhoto.aspx, where there is a larger image displayed. Also on this page the user can edit the photographer and description which is stored in a database, but I'm also trying to write that information to the EXIF header of the image. Futhermore, I have buttons to rotate the image left or right using an ImageMagick command. Sometimes the rotate buttons work and sometimes they don't. Sometimes, information is added to the EXIF header and sometimes it tells me the "process cannot access the file because it is being used by another process." Both functionalities will work if the aspx page stays loaded in the browser for a while, like 15-20 minutes. I cannot figure out why. Can someone assist me with this issue? Thanks....

protected void btnRotLeft_Click(object sender, EventArgs e)
{
    try
    {
        Image img = (Image)FormView1.FindControl("Image1");
        string imgSrc = img.ImageUrl;
        string uncPath = imgSrc.Replace("http://intranet/FieldPics/PicsN/", "//server/LV_N/FieldPics/");    
        string arg = @"convert """ + uncPath + @""" -rotate -90 """ + uncPath + @"""";

        callImgMagick(arg);

        displayImg(img.ImageUrl, 3000);
    }
    catch (Exception ex)
    {
        lblError.Text = ex.Message;
    }
}



protected void btnRotRight_Click(object sender, EventArgs e)
{
    try
    {
        Image img = (Image)FormView1.FindControl("Image1");
        string imgSrc = img.ImageUrl;
        string uncPath = imgSrc.Replace("http://intranet/FieldPics/PicsN/", "//server/LV_N/FieldPics/");    
        string arg = @"convert """ + uncPath + @""" -rotate 90 """ + uncPath + @"""";
        callImgMagick(arg);           
        displayImg(img.ImageUrl, 3000);
    }
    catch (Exception ex)
    {
        lblError.Text = ex.Message;
    }
}



protected void callImgMagick(string fileargs)
{

    try
    {
    System.Diagnostics.Process proc = new System.Diagnostics.Process();

    proc.StartInfo.Arguments = fileargs;

    proc.StartInfo.FileName = Server.MapPath(@"MagickCMD.exe");        
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.CreateNoWindow = true;
    proc.StartInfo.RedirectStandardOutput = false;
    proc.StartInfo.RedirectStandardError = true;
    proc.Start();
    lblError.Text = proc.StandardError.ReadToEnd();        
    proc.WaitForExit();
    //proc.Kill();
    }
    catch (Exception ex)
    {
        lblError.Text = ex.Message;
    }
}


protected void displayImg(string imgSrc, int delay)
{
    Thread.Sleep(delay);
    Image img = (Image)FormView1.FindControl("Image1");
    img.ImageUrl = imgSrc;
}



protected void btnUpdate_Click(object sender, EventArgs e)
{
    string strConnString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
    using (SqlConnection con = new SqlConnection(strConnString))
    {
        try
        {
            con.Open();

            string pID = Request.QueryString["photoid"];
            SqlCommand cmd = new SqlCommand("UPDATE [picTable] SET [photoBy] = @photoBy, [photoDesc] = @photoDesc, [photoPublic] = @photoPublic WHERE id = @pID", con);
            TextBox txtPhotoBy = (TextBox)FormView1.FindControl("txtPhotoBy");
            cmd.Parameters.AddWithValue("@photoBy", txtPhotoBy.Text);
            TextBox txtDescription = (TextBox)FormView1.FindControl("txtDescription");
            cmd.Parameters.AddWithValue("@photoDesc", txtDescription.Text);
            DropDownList PublicList = (DropDownList)FormView1.FindControl("PublicList");
            cmd.Parameters.AddWithValue("@photoPublic", PublicList.Text);
            cmd.Parameters.AddWithValue("@pID", pID);
            cmd.ExecuteNonQuery();
            cmd.Dispose();

            Image img = (Image)FormView1.FindControl("Image1");
            string imgSrc = img.ImageUrl;
            img.ImageUrl = "";
            string uncPath = imgSrc.Replace("http://intranet/FieldPics/PicsN/", "//server/LV_N/FieldPics/");

            Encoding _Encoding = Encoding.UTF8;
            String m_currImageFileTemp = Path.GetTempPath() + "__exifEditor__" + Path.GetRandomFileName();
            File.Copy(uncPath, m_currImageFileTemp);
            System.Drawing.Image theImage = null;
            try
            {
                theImage = new System.Drawing.Bitmap(m_currImageFileTemp);

                PropertyItem imgDesc = theImage.GetPropertyItem(0x010E);
                imgDesc.Value = _Encoding.GetBytes(txtDescription.Text + '\0');
                theImage.SetPropertyItem(imgDesc);

                //fldPic.Save(uncPath, System.Drawing.Imaging.ImageFormat.Jpeg);
                SaveJpeg(uncPath, theImage, 99);

            }
            finally
            {
                if (theImage != null)
                    theImage.Dispose();
            }        

            //ShowMessage("Image Data Updated Successfully!");
            //Thread.Sleep(1000);                
            FormView1.DataBind();
        }
        catch (SqlException ex)
        {
            ShowMessage(ex.Message);
        }
        finally
        {
            con.Close();
        }
    }

}


void ShowMessage(string msg)
{
    ClientScript.RegisterStartupScript(Page.GetType(), "validation", "<script language='javascript'>alert('" + msg + "');</script>");
}


public static void SaveJpeg(string path, System.Drawing.Image img, int quality)
{
    EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
    ImageCodecInfo jpegCodec = GetEncoderInfo(@"image/jpeg");
    EncoderParameters encoderParams = new EncoderParameters(1);
    encoderParams.Param[0] = qualityParam;

    System.IO.MemoryStream mss = null;
    try
    {
        mss = new System.IO.MemoryStream();

        File.Delete(path);
        System.IO.FileStream fs = null;
        try
        {
            fs = new System.IO.FileStream(path, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite);

            img.Save(mss, jpegCodec, encoderParams);
            byte[] matriz = mss.ToArray();
            fs.Write(matriz, 0, matriz.Length);
            fs.Close();

        }
        finally
        {
            if (fs != null)
                fs.Dispose();
        }
        mss.Close();

    }
    finally
    {
        if (mss != null)
            mss.Dispose();
    }

}



private static ImageCodecInfo GetEncoderInfo(String mimeType)
{
    int j;
    ImageCodecInfo[] encoders;
    encoders = ImageCodecInfo.GetImageEncoders();
    for (j = 0; j < encoders.Length; ++j)
    {
        if (encoders[j].MimeType == mimeType)
            return encoders[j];
    }
    return null;
}

Open in new window


 I tried using a PhotoHelper class but it's performing the same.
<asp:Image ID="Image1" runat="server" Width="1000px" ImageUrl='<%# Eval("id", "GetPhoto.aspx?photoid={0}") %>' />



public static Image GetPhoto(int photoid)
{
    string sql = "SELECT fullPath FROM fieldPics WHERE id = @id";
    SqlParameter[] p = new SqlParameter[1];
    p[0] = new SqlParameter("@id", photoid);
    SqlDataReader reader = SqlHelper.ExecuteReader(sql, p);
    string imagePath = null;
    while (reader.Read())
    {
        imagePath = reader.GetValue(0).ToString();
    }
    reader.Close();
    //Image bigImage = Image.FromFile(imagePath);
    //return bigImage;

    Encoding _Encoding = Encoding.UTF8;
    String m_currImageFileTemp = Path.GetTempPath() + Path.GetRandomFileName();
    File.Copy(imagePath, m_currImageFileTemp);
    System.Drawing.Image theImage = new System.Drawing.Bitmap(m_currImageFileTemp);
    return theImage;
}


protected void btnUpdate_Click(object sender, EventArgs e)
{
    string strConnString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
    using (SqlConnection con = new SqlConnection(strConnString))
    {
        try
        {
            con.Open();

            string pID = Request.QueryString["photoid"];
            SqlCommand cmd = new SqlCommand("UPDATE [picTable] SET [photoBy] = @photoBy, [photoDesc] = @photoDesc, [photoPublic] = @photoPublic WHERE id = @pID", con);
            TextBox txtPhotoBy = (TextBox)FormView1.FindControl("txtPhotoBy");
            cmd.Parameters.AddWithValue("@photoBy", txtPhotoBy.Text);
            TextBox txtDescription = (TextBox)FormView1.FindControl("txtDescription");
            cmd.Parameters.AddWithValue("@photoDesc", txtDescription.Text);
            DropDownList PublicList = (DropDownList)FormView1.FindControl("PublicList");
            cmd.Parameters.AddWithValue("@photoPublic", PublicList.Text);
            cmd.Parameters.AddWithValue("@pID", pID);
            cmd.ExecuteNonQuery();
            cmd.Dispose();

            SqlParameter[] p = new SqlParameter[1];
            p[0] = new SqlParameter("@photoid", Request.QueryString["photoid"]);
            string uncPath = (string)SqlHelper.ExecuteScalar("select replace(fullPath,'\', '/') as fullPath from fieldPics where id = @photoid", p);

            Encoding _Encoding = Encoding.UTF8;
            String m_currImageFileTemp = Path.GetTempPath() + "__exifEditor__" + Path.GetRandomFileName();
            File.Copy(uncPath, m_currImageFileTemp);
            System.Drawing.Image theImage = null;
            try
            {
                theImage = new System.Drawing.Bitmap(m_currImageFileTemp);

                PropertyItem imgDesc = theImage.GetPropertyItem(0x010E);
                imgDesc.Value = _Encoding.GetBytes(txtDescription.Text + '\0');
                theImage.SetPropertyItem(imgDesc);

                //fldPic.Save(uncPath, System.Drawing.Imaging.ImageFormat.Jpeg);
                SaveJpeg(uncPath, theImage, 99);

            }
            finally
            {
                if (theImage != null)
                    theImage.Dispose();
            }        

            //ShowMessage("Image Data Updated Successfully!");
            //Thread.Sleep(1000);                
            FormView1.DataBind();
        }
        catch (SqlException ex)
        {
            ShowMessage(ex.Message);
        }
        finally
        {
            con.Close();
        }
    }

}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Nate_LR
Nate_LR

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial