c#中的高性能位图绘图解决方案

时间:2013-08-27 21:52:38

标签: c# performance asp.net-mvc-4 bitmap gdi+

我有一个用例,我需要渲染一个位图拼贴作为预览。该应用程序是作为基于MVC的REST服务实现的,我有一个相当普遍的实现:

using (var bitmap = new Bitmap((int)maxWidth, (int)maxHeight))
{
using (var graphic = Graphics.FromImage(bitmap))
{
    graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;

    // now again for each mod
    foreach (var mod in mods)
    {
        var frame = frames.First(f => f.Index == mod.FrameIndex);
        var fileInfo = GetFileInfo(mod);
        using (var modImage = Image.FromFile(fileInfo.FullName))
        {
            graphic.DrawImage(modImage, (int)frame.Left, (int)frame.Top);
        }
    }

    bitmap.Save(previewFileName);
}
}

虽然这段代码运行良好,但它的表现非常差(特别是对于较大的图像)。我也愿意使用第三方库,我只需要一个性能更快的解决方案。

任何帮助都会受到赞赏。

更新

为了澄清用例,缓存没有帮助。这些图像由客户上传,然后他们请求预览所选拼贴画。这是将图像写入拼贴画的速度很慢。

3 个答案:

答案 0 :(得分:1)

我刚刚意识到你正在以原始大小绘制modImages(因为你使用的是仅采用左坐标和顶坐标的覆盖)。如果这就是你想要的,你也可以使用DrawImageUnscaled() - 图形类的方法,这应该快得多:

    var frame = frames.First(f => f.Index == mod.FrameIndex);
    var fileInfo = GetFileInfo(mod);
    using (var modImage = Image.FromFile(fileInfo.FullName))
    {
        graphic.DrawImageUnscaled(modImage, (int)frame.Left, (int)frame.Top);
    }

答案 1 :(得分:0)

图像质量有多重要?如果你需要更快的结果,你应该尝试InterpolationMode.NearestNeighbour,这应该更快,但结果将是相当低质量。 HeighQualityBicubic(您当前使用的)会产生最佳效果,但性能最低。

答案 2 :(得分:0)

如果你有一个静态的缩略图数,类似于Netflix,我会在内存中创建一个Cache来保存缩略图位图。这甚至可能是一个静态对象。生成缩略图后,您永远不需要再次生成缩略图。这比每次尝试找到更快的锤子来打击它更简洁。

示例:

if(MyThumbnailImageDictionary["whateverimageId"] != null)
   return (Bitmap)MyThumbnailImageDictionary["whateverimageId"];

如果缩略图是动态的,例如用户上传随机图片,那么这种方法无济于事,因为图像缓存的大小会变得很大。

您可以使用以下代码生成Thubnail,但我不确定它的速度会快多少:

 Image image = Image.FromFile(fileName);
 Image thumb = image.GetThumbnailImage(120, 120, ()=>false, IntPtr.Zero);