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

本文关键字:绘制 解决方案 位图 高性能 | 更新日期: 2023-09-27 18:29:19

我有一个用例,需要渲染位图拼贴作为预览。该应用程序是作为一个基于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);
}
}

虽然此代码运行良好,但性能非常差(尤其是对于较大的图像)。我也对使用第三方库持开放态度,我只需要一个性能更快的解决方案。

任何帮助都将不胜感激。

更新

为了澄清用例,缓存没有帮助。这些图片由客户上传,然后他们要求预览所选拼贴。拼贴画上的图像书写得很慢。

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

我刚刚意识到,您正在以原始大小绘制modImages(因为您使用的覆盖只使用左上坐标)。如果这是你想要的,你也可以使用图形类的DrawImageUnsaled()-方法,它应该更快:

    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);
    }

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

如果你有一个静态数量的缩略图,类似于Netflix,我会在内存中创建一个缓存来保存缩略图位图。这甚至可能是一个静态对象。生成缩略图后,就再也不需要生成缩略图了。这将是一种比每次都试图找到一把更快的锤子来敲击它更干净的方法。

示例:

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

如果缩略图是动态的,例如来自用户上传的随机图片,那么这种方法将没有帮助,因为图像缓存的大小将增长巨大。

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

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