以最小的延迟快速显示非常高分辨率的图像的缩略图

tec*_*hno 8 .net c# system.drawing winforms

我需要在控件中显示高分辨率图像的预览缩略图,以供用户选择。我目前使用ImageListView加载图像。这对于低至中分辨率的图像效果很好。但是,在显示非常高分辨率的图像的缩略图时会出现明显的延迟。可以从https://drive.google.com/open?id=1Qgu_aVXBiMlbHluJFU4fBvmFC45-下载示例图像E81C

图像大小约为5000x3000像素,大小约为12 MB。可以通过使用此图像的1000份副本来复制此问题。

问题屏幕截图在此处上传

https://giphy.com/gifs/ZEH3T3JTfN42OL3J1A

使用后台工作程序加载图像

foreach (var f in filepaths)
{
    imageListView1.Items.Add(f);              
}
Run Code Online (Sandbox Code Playgroud)

1.为了解决此问题,我尝试调整高分辨率图像的大小并将调整大小后的图像添加到ImageListView ...中,但是要进行重新调整大小会浪费大量时间,并且缩略图生成速度很慢。

Bitmap x = UpdatedResizeImage2(new Bitmap(f), new Size(1000, 1000));
string q = Path.GetTempPath() + Path.GetFileName(f);
x.Save(Path.GetTempPath() + Path.GetFileName(f));
x.Dispose();
imageListView1.Items.Add(Path.GetTempPath() + Path.GetFileName(f));
Run Code Online (Sandbox Code Playgroud)

2.我也尝试过Image.CreateThumbnail方法,但这也很慢。

有没有更好的方法来解决此问题?

may*_*ʎɐɯ 9

我建议使用图像处理库,例如ImageMagick。

ImageMagick已优化此功能,并且您具有Magick.NET的.NET nuget包。

这很简单明了:

var file = new FileInfo(@"c:\temp\input.jpg");

using (MagickImage image = new MagickImage(file))
{
    {
        image.Thumbnail(new MagickGeometry(100, 100));
        image.Write(@"C:\temp\thumbnail.jpg");
    }
}
Run Code Online (Sandbox Code Playgroud)

我做的例子:

在此处输入图片说明

以下是一些可能有用的文档和参考:


Sim*_*ier 5

您可以使用WPF 互操作并使用DecodePixelWidth/Height 属性。他们使用底层 Windows 成像层技术(“ Windows 成像组件”)来创建优化的缩略图,从而节省大量内存(可能还有 CPU):如何:使用 BitmapImage (XAML)

\n\n

您还可以通过代码使用 WPF/WIC,代码如下(改编自这篇文章Thefastest way to resize images from ASP.NET. And it\xe2\x80\x99s (more)supported-ish..您只需要添加对PresentationCore 和WindowsBase 的引用,这对于桌面应用程序来说不应该是问题。

\n\n
    // needs System.Windows.Media & System.Windows.Media.Imaging (PresentationCore & WindowsBase)\n    public static void SaveThumbnail(string absoluteFilePath, int thumbnailSize)\n    {\n        if (absoluteFilePath == null)\n            throw new ArgumentNullException(absoluteFilePath);\n\n        var bitmap = BitmapDecoder.Create(new Uri(absoluteFilePath), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None).Frames[0];\n        int width;\n        int height;\n        if (bitmap.Width > bitmap.Height)\n        {\n            width = thumbnailSize;\n            height = (int)(bitmap.Height * thumbnailSize / bitmap.Width);\n        }\n        else\n        {\n            width = (int)(bitmap.Width * thumbnailSize / bitmap.Height);\n            height = thumbnailSize;\n        }\n\n        var resized = BitmapFrame.Create(new TransformedBitmap(bitmap, new ScaleTransform(width / bitmap.Width * 96 / bitmap.DpiX, height / bitmap.Height * 96 / bitmap.DpiY, 0, 0)));\n        var encoder = new PngBitmapEncoder();\n        encoder.Frames.Add(resized);\n        var thumbnailFilePath = Path.ChangeExtension(absoluteFilePath, thumbnailSize + Path.GetExtension(absoluteFilePath));\n        using (var stream = File.OpenWrite(thumbnailFilePath))\n        {\n            encoder.Save(stream);\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

除此之外,还有很多工具,如 MagicScaler、FreeImage ImageSharp、ImageMagick、Imazen 等。大多数工具都是为 ASP.NET/Web 服务器场景编写的(官方不支持 WPF,但可以使用,请阅读文章),并且也是交叉的-您似乎不需要的平台。我不确定它们通常比内置 Windows 技术更快或使用更少的内存,但您应该在您的上下文中测试所有这些。

\n\n

PS:否则就没有灵丹妙药,更大的图像需要更多时间。

\n


jcu*_*itt 5

还有NetVips,libvips 的 C# 绑定。

它比 Magick.NET 快很多:快 3 倍到 10 倍,具体取决于基准测试。

缩略图很简单:

using NetVips;

var image = Image.Thumbnail("some-image.jpg", 128);
image.WriteToFile("x.jpg");
Run Code Online (Sandbox Code Playgroud)

文档里有介绍。