Search This Blog

Tuesday 27 November 2012

How to crop image using ASP.Net/C# OR Cropping image in C# before upload


Crop images before upload to the server in C#/ASP.Net
In our previous post we demonstrate how we can re size image using C# or Create thumbnail image using ASP.Net. Here we are demonstrating how we can crop images using ASP.Net application using Jquery and C#. In some applications we need to upload images and we need only some portion of the images to get clear picture on the photo. In this case we need to give an option to users to crop image before they are uploading the image.
Include Jquery file/CSS files to the application. 
First of all we need to include following jquery/CSS files to the application.
1.       jquery.min.js
2.       jquery.Jcrop.js
3.       jquery.Jcrop.css
Simple steps to crop image using ASP.Net,C#,Jquery
In this application we are having a browse option for selecting an image. Once we selected a image it will display int the screen.
Crop image using ASP.net C#
Select an image to crop using ASP.Net C# Jquery
In the next step we will have the option to select an area to crop the image. Once we selected an area we can click crop button on the screen.
Crop image using ASP.Net C#
Select image area to crop
Then the selected area will be cropped and displayed in the screen.
Crop image using ASP.Net C#
Cropped area of the image
ASPX Page for crop images using Jquery 
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CropImage.aspx.cs" 
Inherits="ExperimentLab.CropImage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
 <title>Crop Image</title>
 <link href="Styles/jquery.Jcrop.css" rel="stylesheet" type="text/css" />
 <script type="text/javascript" 
 src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
 <script type="text/javascript" src="Scripts/jquery.Jcrop.js"></script>
 <script type="text/javascript">
 jQuery(document).ready(function () {
 jQuery('#imgCrop').Jcrop({
 onSelect: storeCoords
 });
 });
function storeCoords(c) {
 jQuery('#X').val(c.x);
 jQuery('#Y').val(c.y);
 jQuery('#W').val(c.w);
 jQuery('#H').val(c.h);
 };
</script>
</head>
<body>
 <form id="form1" runat="server">
 <div>
 <asp:Panel ID="pnlUpload" runat="server">
 <asp:FileUpload ID="Upload" runat="server" />
 <br />
 <asp:Button ID="btnUpload" runat="server" 
 OnClick="btnUpload_Click" Text="Upload" />
 <asp:Label ID="lblError" runat="server" Visible="false" />
 </asp:Panel>
 <asp:Panel ID="pnlCrop" runat="server" Visible="false">
 <asp:Image ID="imgCrop" runat="server" />
 <br />
 <asp:HiddenField ID="X" runat="server" />
 <asp:HiddenField ID="Y" runat="server" />
 <asp:HiddenField ID="W" runat="server" />
 <asp:HiddenField ID="H" runat="server" />
 <asp:Button ID="btnCrop" runat="server" Text="Crop" 
 OnClick="btnCrop_Click" />
 </asp:Panel>
 <asp:Panel ID="pnlCropped" runat="server" Visible="false">
 <asp:Image ID="imgCropped" runat="server" />
 </asp:Panel>
 </div>
 </form>
</body>
</html>
Code Behind of the ASPX page for Crop image using ASP.Net/C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using SD = System.Drawing;
using System.Drawing.Drawing2D;
namespace ExperimentLab
{
public partial class CropImage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
String path = HttpContext.Current.Request.PhysicalApplicationPath + "images\\";
protected void btnUpload_Click(object sender, EventArgs e)
{
Boolean FileOK = false;
Boolean FileSaved = false; 
if (Upload.HasFile)
{
Session["WorkingImage"] = Upload.FileName;
String FileExtension =
Path.GetExtension(Session["WorkingImage"].ToString()).ToLower();
String[] allowedExtensions = { ".png", ".jpeg", ".jpg", ".gif" };
for (int i = 0; i < allowedExtensions.Length; i++)
{
if (FileExtension == allowedExtensions[i])
{
 FileOK = true;
}
}
}
if (FileOK)
{
try
{
Upload.PostedFile.SaveAs(path + Session["WorkingImage"]);
FileSaved = true;
}
catch (Exception ex)
{
lblError.Text = "File could not be uploaded." + ex.Message.ToString();
lblError.Visible = true;
FileSaved = false;
}
}
else
{
lblError.Text = "Cannot accept files of this type.";
lblError.Visible = true;
}
if (FileSaved)
{
pnlUpload.Visible = false;
pnlCrop.Visible = true;
imgCrop.ImageUrl = "images/" + Session["WorkingImage"].ToString();
}
}
protected void btnCrop_Click(object sender, EventArgs e)
{
string ImageName = Session["WorkingImage"].ToString();
int w = Convert.ToInt32(W.Value);
int h = Convert.ToInt32(H.Value);
int x = Convert.ToInt32(X.Value);
int y = Convert.ToInt32(Y.Value);
byte[] CropImage = Crop(path + ImageName, w, h, x, y);
using (MemoryStream ms = new MemoryStream(CropImage, 0, CropImage.Length))
{
ms.Write(CropImage, 0, CropImage.Length);
using (SD.Image CroppedImage = SD.Image.FromStream(ms, true))
{
string SaveTo = path + "crop" + ImageName;
CroppedImage.Save(SaveTo, CroppedImage.RawFormat);
pnlCrop.Visible = false;
pnlCropped.Visible = true;
imgCropped.ImageUrl = "images/crop" + ImageName;
}
}
}
static byte[] Crop(string Img, int Width, int Height, int X, int Y)
{
try
{
using (SD.Image OriginalImage = SD.Image.FromFile(Img))
{
using (SD.Bitmap bmp = new SD.Bitmap(Width, Height))
{
 bmp.SetResolution(OriginalImage.HorizontalResolution, 
 OriginalImage.VerticalResolution);
 using (SD.Graphics Graphic = SD.Graphics.FromImage(bmp))
 {
 Graphic.SmoothingMode = SmoothingMode.AntiAlias;
 Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
 Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
 Graphic.DrawImage(OriginalImage, new SD.Rectangle(0, 0, Width, Height),
 X, Y, Width, Height, SD.GraphicsUnit.Pixel);
 MemoryStream ms = new MemoryStream();
 bmp.Save(ms, OriginalImage.RawFormat);
 return ms.GetBuffer();
 }
}
}
}
catch (Exception Ex)
{
throw (Ex);
}
}
}
}

3 comments:

  1. I'm on the fence about this, while more customization is good, I have a feeling this is a "in-progress" update, it just feels incomplete and half-way there.
    We use badge layout for apps on design approvals (visual projects), so the image being displayed is important. Old layout "feels like" it had larger images,
    maybe because the images were cropped more loosely so it's easier to tell which project it was at quick glance. Now the image is cropped closer, making it
    harder to scan thru at quick glance. I find myself needing to click into the project more often than usual. Which makes the whole user experience less
    efficient.
    I have a couple suggestions that might make it work better:
    1. Increase the height of the window the cover image is being displayed.
    2. Let us to choose which image to be displayed as "cover" (like how Pinterest handles cover images of each board, was hoping for this for a long time)
    3. Let us adjust which part of the image to show and how tight or loose the crop is (with a fixed window, let us move the image around and maybe enlarge or
    shrink it to control what shows thru the window. Pinterest does a limited form of this, which is very useful in making the cover image relevant)
    4. Allow Cover Image to be ordered in different hierarchy (currently every element can be ordered differently except the Cover Image, it seems to be stuck
    in the 2nd spot, would like the option to set it on another spot in the layout. This one seems like an easy fix, since you guys allow that for every other
    element already)

    ReplyDelete
  2. I'm on the fence about this, while more customization is good, I have a feeling this is a "in-progress" update, it just feels incomplete and half-way there.
    We use badge layout for apps on design approvals (visual projects), so the image being displayed is important. Old layout "feels like" it had larger images,
    maybe because the images were cropped more loosely so it's easier to tell which project it was at quick glance. Now the image is cropped closer, making it
    harder to scan thru at quick glance. I find myself needing to click into the project more often than usual. Which makes the whole user experience less
    efficient.
    I have a couple suggestions that might make it work better:
    1. Increase the height of the window the cover image is being displayed.
    2. Let us to choose which image to be displayed as "cover" (like how Pinterest handles cover images of each board, was hoping for this for a long time)
    3. Let us adjust which part of the image to show and how tight or loose the crop is (with a fixed window, let us move the image around and maybe enlarge or
    shrink it to control what shows thru the window. Pinterest does a limited form of this, which is very useful in making the cover image relevant)
    4. Allow Cover Image to be ordered in different hierarchy (currently every element can be ordered differently except the Cover Image, it seems to be stuck
    in the 2nd spot, would like the option to set it on another spot in the layout. This one seems like an easy fix, since you guys allow that for every other
    element already)

    ReplyDelete
  3. I'm on the fence about this, while more customization is good, I have a feeling this is a "in-progress" update, it just feels incomplete and half-way there.
    We use badge layout for apps on design approvals (visual projects), so the image being displayed is important. Old layout "feels like" it had larger images,
    maybe because the images were cropped more loosely so it's easier to tell which project it was at quick glance. Now the image is cropped closer, making it
    harder to scan thru at quick glance. I find myself needing to click into the project more often than usual. Which makes the whole user experience less
    efficient.
    I have a couple suggestions that might make it work better:
    1. Increase the height of the window the cover image is being displayed.
    2. Let us to choose which image to be displayed as "cover" (like how Pinterest handles cover images of each board, was hoping for this for a long time)
    3. Let us adjust which part of the image to show and how tight or loose the crop is (with a fixed window, let us move the image around and maybe enlarge or
    shrink it to control what shows thru the window. Pinterest does a limited form of this, which is very useful in making the cover image relevant)
    4. Allow Cover Image to be ordered in different hierarchy (currently every element can be ordered differently except the Cover Image, it seems to be stuck
    in the 2nd spot, would like the option to set it on another spot in the layout. This one seems like an easy fix, since you guys allow that for every other
    element already)

    ReplyDelete