【问题标题】:C# mvc image upload resizing server sideC# mvc 图片上传调整大小服务器端
【发布时间】:2011-06-11 20:30:30
【问题描述】:

我有一个网络应用程序,用户可以在其中上传图像。我遇到的当前问题是正在上传的图像以原始格式保存到数据库中。当在网页上使用图像时,这会导致很多性能问题。我使用 dotTrace 来分析应用程序,并且在从数据库处理图像时发现了严重问题。

我的想法是在将图像上传到服务器时调整其大小。以我希望应用程序在用户上传新图像时执行以下示例;

  1. 用户上传图片
  2. 正在将图像大小调整为 72 dpi 中 7.500 x 7.500 像素的大小
  3. 图像正在保存到数据库中
  4. 原始文件被处理

唯一存储的图像是上面提到的那个,网络应用程序包含动态调整大小的技术。

我已经在这里阅读了几个关于 SO 的主题。他们中的大多数将我指向 ImageMagick 的方向。这个工具在我的公司已经很熟悉了,并且正在 PHP 项目中使用。但是这个工具有什么好的和稳定的发布的 C# 包装器吗?我已经找到了以下工具,但它们要么处于 Beta 版、Alpha 版或当前未更新。

ImageMagick.NET

ImageMagick APP

我还在 SO 上找到了 this 主题。在本主题中,提供了以下代码示例;

private static Image CreateReducedImage(Image imgOrig, Size newSize)
{
    var newBm = new Bitmap(newSize.Width, newSize.Height);
    using (var newGrapics = Graphics.FromImage(newBm))
    {
        newGrapics.CompositingQuality = CompositingQuality.HighSpeed;
        newGrapics.SmoothingMode = SmoothingMode.HighSpeed;
        newGrapics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        newGrapics.DrawImage(imgOrig, new Rectangle(0, 0, newSize.Width, newSize.Height));
    }

    return newBm;
}

简而言之,我的问题;

  • 使用上述示例在性能方面有什么优势吗?
  • 我可以使用 ImageMagick 的良好且可靠的 C# 包装器来执行此操作吗?

欢迎任何其他与表演有关的好建议!

【问题讨论】:

  • imageresizing.net 是要走的路。它经过测试,可靠,并且在低信任度下工作。它可以轻松处理各种格式,并且可以在一行代码中调用。极其灵活且功能强大的库。

标签: c# asp.net asp.net-mvc image-processing


【解决方案1】:

我们使用后一种方法 - 我无法评论性能,但它确实使处理依赖关系更简单。

但是,需要注意的一点是,如果您的用户能够上传各种格式的图像,上述代码可能过于简单。底层库 (GDI+) 存在许多颜色格式的问题,但它也取决于操作系统版本。这是我们使用的代码的核心:

    // GDI+ has problems with lots of image formats, and it also chokes on unknown ones (like CMYK).
// Therefore, we're going to take a whitelist approach.
// see http://bmpinroad.blogspot.com/2006/04/file-formats-pixel-formats.html
// also see http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/c626a478-e5ef-4a5e-9a73-599b3b7a6ecc
PixelFormat format = originalImage.PixelFormat;

if (format == PixelFormat.Format16bppArgb1555 ||
    format == PixelFormat.Format64bppArgb)
{
    // try to preserve transparency
    format = PixelFormat.Format32bppArgb;
}
else if (format == PixelFormat.Format64bppPArgb)
{
    // try to preserve pre-multiplied transparency
    format = PixelFormat.Format32bppPArgb;
}
else if (format != PixelFormat.Format24bppRgb && format != PixelFormat.Format32bppRgb)
{
    format = PixelFormat.Format24bppRgb;
}


// GIF saving is probably still an issue.  If we ever need to tackle it, see the following:
// http://support.microsoft.com/kb/319061
// http://www.bobpowell.net/giftransparency.htm
// http://support.microsoft.com/kb/318343


using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, format))
{
    using (Graphics Canvas = Graphics.FromImage(newImage))
    {
        using (ImageAttributes attr = new ImageAttributes())
        {
            attr.SetWrapMode(WrapMode.TileFlipXY);

            Canvas.SmoothingMode = SmoothingMode.AntiAlias;
            Canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
            Canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
            Canvas.DrawImage(originalImage, new Rectangle(new Point(0, 0), newSize), srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, GraphicsUnit.Pixel, attr);
            newImage.Save(outputImageStream, originalImage.RawFormat);
        }
    }
}

【讨论】:

  • 我们可以为客户确定上传的格式。这个想法是在上传 GIF(因为动画)和 PNG(因为透明)时保留原始文件。所有其他格式(主要是 JPG,有时是 TIFF 的 BMP)使用这种方法会导致任何问题吗?还是 GDI+ 方法?
  • 如果我想将像素格式设置为 72DPI。我怎样才能做到这一点?使用哪种格式?
  • Bitmap 对象(在本例中为 newImage)具有 Horizo​​ntalResolution 和 VerticalResolution 属性,您可以修改这些属性来设置每英寸的像素数。 GIF 可能更难。您必须处理透明度并使用其原始调色板重新绘制图像 - 请参阅代码 cmets 中的链接。对于动画,我认为您可以使用 originalImage.SelectActiveFrame() 循环遍历图像的帧,但我没有尝试过,也不确定在完成后如何重新组合帧。
  • 未使用此方法的精确副本。但被接受为解决方案,因为它是最接近的答案。感谢您的帮助和示例
【解决方案2】:

我从未使用过 ImageMagic,但我使用过 GDI+ 图像调整大小功能,包括在一个每天生成和调整大小 100,000 多张图像且没有性能问题的网站上。

我会说使用 GDI+ 方法就可以了。不用担心包装外部工具或框架。

【讨论】:

【解决方案3】:

我在 Umbraco 网站中使用过 ImageGen。 (它当然与 Umbraco 无关,它适用于任何 ASP.NET 应用程序,只是碰巧我使用的一些 Umbraco 包需要它。)它使用简单,你也许可以免费使用版本...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 2017-01-08
    • 2014-11-29
    • 1970-01-01
    • 2011-08-25
    • 2014-08-26
    • 2011-05-28
    相关资源
    最近更新 更多