C#裁剪后缩放裁剪后的图像

3

我正在尝试构建这个类(用于在ASP.NET网站中使用),它将根据自定义的宽度、高度、X和Y裁剪图像,然后将结果图像缩放到自定义的宽度、高度,并将其保存在服务器上的目录中,返回该图像的URL。

我将通过查询字符串获取这些参数,如下所示:

Default.aspx?x=100&y=300&w=800&h=500&scalew=160&scaleh=100 

所以,这是我目前的成果。
    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;
        }
    }

我将发送这些值:裁剪图像(宽度、高度、x、y),然后缩放裁剪后的图像(scalwidth、scalheight),然后将jpg保存在目录中并返回图像位置的url。那么,最好的方法是什么?

3
有人对这个问题进行了负评,但没有解释原因。拜托各位...不要那样做。如果负评的动机没有在评论中说明,请在为什么您认为这是错误的上发表评论...我认为这个问题不应该被负评,相反我已经回答了它。不是每个人都知道所有的东西。问题作者确实展示了解决自己问题的努力,他已经完成了几乎一半...这里的问题在于 Stack Overflow 的人。 - Miguel Angelo
五年过去了,我仍在问自己同样的问题。 - dvdmn
3个回答

3
在您的asp.net网站或应用程序中创建一个通用处理程序(即ashx文件),并将以下代码放入其中。例如,将其命名为“Handler.ashx”。
现在,在浏览器中使用:Handler.ashx?x=100&y=300&w=800&h=500&scalew=160&scaleh=100 Handler.ashx文件的代码:
<%@ 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;
        }
    }

}

编辑:

有关通用处理程序的一些参考资料:

HTTP 处理程序和 HTTP 模块概述

@ WebHandler - ashx 文件的工作原理。


它确实像我想要的那样工作得很好,但似乎存在一些性能问题,特别是在处理非常大的图像时。因此,我将尝试进行优化。谢谢。 - HamedM
好的,它应该这样做-它会像漏斗一样泄露内存。每个 System.Drawing 对象都必须包装在 using(){} 子句中。此外,这将导致外边缘周围有一个50%的透明边框。 - Lilith River

1

嗯,你已经有可行的代码了,这确实是其中一种方法 - 你可以添加压缩(例如,JPEG格式会使用有损压缩)- 参见这篇文章:http://www.britishdeveloper.co.uk/2011/05/image-resizing-cropping-and-compression.html

然而,我建议不要使用System.Drawing命名空间。根据MSDN文档,在ASP.NET应用程序中使用GDI+(即System.Drawing)是不受支持的。相反,它推荐使用Windows图像组件(即从.NET角度使用WPF Imaging - 它在内部使用WIC)。请参阅此文章,以开始使用WPF裁剪/缩放图像:http://weblogs.asp.net/bleroy/archive/2009/12/10/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi.aspx


好的,看起来有很多组件是使用System.Drawing编写的,但目前还不被支持,这可能导致在某些情况下运行时错误,我会尝试使用WPF Imaging并测试这两种方法。 - HamedM

1

已经存在一个经过充分测试和证明的开源库 - imageresizing.net,支持GDI+、WIC和FreeImage后端。我在2009年编写了它,并发布了60个新版本。它被超过10,000个网站使用,并为一些极大型社交网络站点提供支持。

System.Drawing几乎不可能正确使用。我记录了大约30个陷阱,还有更多即将到来。虽然有可能安全地使用它,但你不会通过复制和粘贴代码来做到这一点。

最好使用一个包装器,它可以从头到尾处理内存管理,并避免所有GDI+和ASP.NET的陷阱。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接