我有一个用例,我需要渲染一个位图拼贴作为预览。该应用程序是作为基于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);
}
}
虽然这段代码运行良好,但它的表现非常差(特别是对于较大的图像)。我也愿意使用第三方库,我只需要一个性能更快的解决方案。
任何帮助都会受到赞赏。
更新
为了澄清用例,缓存没有帮助。这些图像由客户上传,然后他们请求预览所选拼贴画。这是将图像写入拼贴画的速度很慢。
答案 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);