以最小的延迟快速显示非常高分辨率图像的缩略图
Displaying Thumbnails of very high resolution images Fast with Minimal Delay
我需要在控件中显示高分辨率图像的预览缩略图以供用户选择。我目前使用 ImageListView 加载图像。
这适用于中低分辨率 images.But 当显示非常高分辨率图像的缩略图时,有一个明显的 delay.Sample 图像可以从 https://drive.google.com/open?id=1Qgu_aVXBiMlbHluJFU4fBvmFC45-E81C
下载
图像大小约为 5000x3000 像素,大小约为 12 MB.The 使用此图像的 1000 个副本可以复制问题。
问题截屏上传到这里
https://giphy.com/gifs/ZEH3T3JTfN42OL3J1A
图像是使用后台工作程序加载的
foreach (var f in filepaths)
{
imageListView1.Items.Add(f);
}
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));
2. 我也试过Image.CreateThumbnail
方法,但是这个也很慢。
有没有更好的方法来解决这个问题?
我建议使用 ImageMagick 等图像处理库。
ImageMagick 优化了此功能,您有 Magick.NET 一个 nuget .NET 包。
简单明了:
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");
}
}
我做的例子:
以下是一些可能有用的文档和参考资料:
- https://imagemagick.org/Usage/thumbnails/#creation
- http://www.imagemagick.org/Usage/thumbnails/
- https://github.com/dlemstra/Magick.NET
https://www.smashingmagazine.com/2015/06/efficient-image-resizing-with-imagemagick/
https://devblogs.microsoft.com/dotnet/net-core-image-processing/
- https://weblogs.asp.net/bleroy/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi
- Alternatives to System.Drawing for use with ASP.NET?
您可以使用 WPF interop and use the DecodePixelWidth/Height properties. They use underlying Windows imaging layer technology ("Windows Imaging Component") to create an optimized thumbnail, saving lots of memory (and possibly CPU): How to: Use a BitmapImage (XAML)
您也可以通过代码使用 WPF/WIC,代码如下(改编自这篇文章 The fastest way to resize images from ASP.NET. And it’s (more) supported-ish.。您只需要添加对 PresentationCore 和 WindowsBase 的引用即可对于桌面应用程序应该不是问题。
// needs System.Windows.Media & System.Windows.Media.Imaging (PresentationCore & WindowsBase)
public static void SaveThumbnail(string absoluteFilePath, int thumbnailSize)
{
if (absoluteFilePath == null)
throw new ArgumentNullException(absoluteFilePath);
var bitmap = BitmapDecoder.Create(new Uri(absoluteFilePath), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None).Frames[0];
int width;
int height;
if (bitmap.Width > bitmap.Height)
{
width = thumbnailSize;
height = (int)(bitmap.Height * thumbnailSize / bitmap.Width);
}
else
{
width = (int)(bitmap.Width * thumbnailSize / bitmap.Height);
height = thumbnailSize;
}
var resized = BitmapFrame.Create(new TransformedBitmap(bitmap, new ScaleTransform(width / bitmap.Width * 96 / bitmap.DpiX, height / bitmap.Height * 96 / bitmap.DpiY, 0, 0)));
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(resized);
var thumbnailFilePath = Path.ChangeExtension(absoluteFilePath, thumbnailSize + Path.GetExtension(absoluteFilePath));
using (var stream = File.OpenWrite(thumbnailFilePath))
{
encoder.Save(stream);
}
}
否则还有很多工具,如 MagicScaler、FreeImage ImageSharp、ImageMagick、Imazen 等。大多数是为 ASP.NET/Web 服务器场景编写的(官方不支持 WPF)但有效,请阅读文章)并且也是您似乎不需要的跨平台。我不确定它们通常比内置 Windows 技术更快或使用更少的内存,但您应该在您的上下文中测试所有这些。
PS:否则没有灵丹妙药,更大的图像需要更多时间。
还有 NetVips,libvips 的 C# 绑定。
它比 Magick.NET 快很多:between 3x and 10x faster,具体取决于基准。
缩略图很简单:
using NetVips;
var image = Image.Thumbnail("some-image.jpg", 128);
image.WriteToFile("x.jpg");
文档中有 an introduction。
我需要在控件中显示高分辨率图像的预览缩略图以供用户选择。我目前使用 ImageListView 加载图像。 这适用于中低分辨率 images.But 当显示非常高分辨率图像的缩略图时,有一个明显的 delay.Sample 图像可以从 https://drive.google.com/open?id=1Qgu_aVXBiMlbHluJFU4fBvmFC45-E81C
下载图像大小约为 5000x3000 像素,大小约为 12 MB.The 使用此图像的 1000 个副本可以复制问题。
问题截屏上传到这里
https://giphy.com/gifs/ZEH3T3JTfN42OL3J1A
图像是使用后台工作程序加载的
foreach (var f in filepaths)
{
imageListView1.Items.Add(f);
}
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));
2. 我也试过Image.CreateThumbnail
方法,但是这个也很慢。
有没有更好的方法来解决这个问题?
我建议使用 ImageMagick 等图像处理库。
ImageMagick 优化了此功能,您有 Magick.NET 一个 nuget .NET 包。
简单明了:
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");
}
}
我做的例子:
以下是一些可能有用的文档和参考资料:
- https://imagemagick.org/Usage/thumbnails/#creation
- http://www.imagemagick.org/Usage/thumbnails/
- https://github.com/dlemstra/Magick.NET
https://www.smashingmagazine.com/2015/06/efficient-image-resizing-with-imagemagick/
https://devblogs.microsoft.com/dotnet/net-core-image-processing/
- https://weblogs.asp.net/bleroy/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi
- Alternatives to System.Drawing for use with ASP.NET?
您可以使用 WPF interop and use the DecodePixelWidth/Height properties. They use underlying Windows imaging layer technology ("Windows Imaging Component") to create an optimized thumbnail, saving lots of memory (and possibly CPU): How to: Use a BitmapImage (XAML)
您也可以通过代码使用 WPF/WIC,代码如下(改编自这篇文章 The fastest way to resize images from ASP.NET. And it’s (more) supported-ish.。您只需要添加对 PresentationCore 和 WindowsBase 的引用即可对于桌面应用程序应该不是问题。
// needs System.Windows.Media & System.Windows.Media.Imaging (PresentationCore & WindowsBase)
public static void SaveThumbnail(string absoluteFilePath, int thumbnailSize)
{
if (absoluteFilePath == null)
throw new ArgumentNullException(absoluteFilePath);
var bitmap = BitmapDecoder.Create(new Uri(absoluteFilePath), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None).Frames[0];
int width;
int height;
if (bitmap.Width > bitmap.Height)
{
width = thumbnailSize;
height = (int)(bitmap.Height * thumbnailSize / bitmap.Width);
}
else
{
width = (int)(bitmap.Width * thumbnailSize / bitmap.Height);
height = thumbnailSize;
}
var resized = BitmapFrame.Create(new TransformedBitmap(bitmap, new ScaleTransform(width / bitmap.Width * 96 / bitmap.DpiX, height / bitmap.Height * 96 / bitmap.DpiY, 0, 0)));
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(resized);
var thumbnailFilePath = Path.ChangeExtension(absoluteFilePath, thumbnailSize + Path.GetExtension(absoluteFilePath));
using (var stream = File.OpenWrite(thumbnailFilePath))
{
encoder.Save(stream);
}
}
否则还有很多工具,如 MagicScaler、FreeImage ImageSharp、ImageMagick、Imazen 等。大多数是为 ASP.NET/Web 服务器场景编写的(官方不支持 WPF)但有效,请阅读文章)并且也是您似乎不需要的跨平台。我不确定它们通常比内置 Windows 技术更快或使用更少的内存,但您应该在您的上下文中测试所有这些。
PS:否则没有灵丹妙药,更大的图像需要更多时间。
还有 NetVips,libvips 的 C# 绑定。
它比 Magick.NET 快很多:between 3x and 10x faster,具体取决于基准。
缩略图很简单:
using NetVips;
var image = Image.Thumbnail("some-image.jpg", 128);
image.WriteToFile("x.jpg");
文档中有 an introduction。