C# Crop then scale the Cropped Image
I'm trying to build this class (to use in ASP.NET site) that will Crop Image given custom Width,Height X,Y, then take the result image and Scale it to Custom Width, Height, And save in directory on the server return url of this image.
And i will get these paramerts in querystring like this
Default.aspx?x=100&y=300&w=800&h=500&scalew=160&scaleh=100
So this is what i got so far
public static Image CustomCrop(int width, int height, int x, int y, int scalwidth, int scalheight)
{
try
{
Image image = Image.FromFile("Images/none.jpg");
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
bmp.SetResolution(80, 60);
Graphics gfx = Graphics.FromImage(bmp);
gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(image, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel);
return bmp;
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
return null;
}
}
I will send these values Crop Image (width, height, x, y) then Scale the Croped image (sc开发者_Python百科alwidth, scalheight) then save jpg in directory and return url for the image location
So what is the best way to this?
Create a Generic Handler
(i.e. ashx file) in your asp.net website or application, and place the following code inside it. Call it for example "Handler.ashx".
Now, in the browser use: Handler.ashx?x=100&y=300&w=800&h=500&scalew=160&scaleh=100
Code of Handler.ashx file:
<%@ WebHandler Language="C#" Class="Handler" %>
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
public class Handler : IHttpHandler {
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "image/jpeg";
int x = int.Parse(context.Request["x"]);
int y = int.Parse(context.Request["y"]);
int h = int.Parse(context.Request["h"]);
int w = int.Parse(context.Request["w"]);
int scalew = int.Parse(context.Request["scalew"]);
int scaleh = int.Parse(context.Request["scaleh"]);
using (Image img = CustomCrop(w, h, x, y, scalew, scaleh))
img.Save(context.Response.OutputStream,ImageFormat.Jpeg);
}
public static Image CustomCrop(int width, int height, int x, int y, int scalwidth, int scalheight)
{
try
{
Image image = Image.FromFile("c:\\x.jpg");
Bitmap bmp = new Bitmap(scalwidth, scalheight, PixelFormat.Format24bppRgb);
bmp.SetResolution(80, 60);
Graphics gfx = Graphics.FromImage(bmp);
gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(image, new Rectangle(0, 0, scalwidth, scalheight), x, y, width, height, GraphicsUnit.Pixel);
return bmp;
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
return null;
}
}
public bool IsReusable {
get {
return false;
}
}
}
EDIT:
Some reference about Generic Handlers:
HTTP Handlers and HTTP Modules Overview
@ WebHandler - how ashx files work.
Well, you already have working code which is indeed one of the way - you can perhaps add compression (for example, JPEG format would use lossy compression) - see this article: http://www.britishdeveloper.co.uk/2011/05/image-resizing-cropping-and-compression.html
However, I will recommend not to use System.Drawing
namespace. As per MSDN documentation, using GDI+ (that's System.Drawing) in ASP.NET applications is not supported. Rather, it recommends Windows Imaging Components (i.e. use WPF Imaging from .NET perspective - it uses WIC internally). See this article that will start you using WPF for cropping/scaling images: http://weblogs.asp.net/bleroy/archive/2009/12/10/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi.aspx
A well tested and proven open-source library already exists for this - imageresizing.net, which supports both GDI+, WIC, and FreeImage backends. I wrote it in 2009, and have released 60 new versions since then. It's used on over 10,000 websites, and powers some extremely large social networking sites.
System.Drawing is nearly impossible to use correctly. I've documented about 30 pitfalls, and more are soon to follow. It's possible to do it safely, but you're not going to do it by copying and pasting code.
It's better to use a wrapper than handles memory management for you from end-to-end, and avoids all the GDI+ and ASP.NET pitfalls.
精彩评论