I need to show the preview thumbnails of high resolution images in a control for user selection. I currently use ImageListView to load images. This works fine for low to medium resolution images.But when it comes to showing thumbnails of very high resolution images there is a noticeable delay.Sample image can be downloaded from https://drive.google.com/open?id=1Qgu_aVXBiMlbHluJFU4fBvmFC45-E81C
The image size is around 5000x3000 pixels and size is around 12 MB.The issue can be replicated by using 1000 copies of this image.
The issue screen capture is uploaded here
https://giphy.com/gifs/ZEH3T3JTfN42OL3J1A
The images are loaded using a background worker
foreach (var f in filepaths)
{
imageListView1.Items.Add(f);
}
1. In order to solve this issue I tried resizing large resolution images and adding the resized image to ImageListView ... but for resizing there is a heavy time consumption and thumbnail generation is slow.
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. I have also tried Image.CreateThumbnail
Method but this is also quite slow.
Is there a better way to solve this issue?
I would suggest using image processing library such ImageMagick.
ImageMagick has optimized this feature and you have Magick.NET a nuget package for .NET.
It is simple and straight forward:
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");
}
}
example I made:
Here is some documentation and references that might be useful:
https://www.smashingmagazine.com/2015/06/efficient-image-resizing-with-imagemagick/
https://devblogs.microsoft.com/dotnet/net-core-image-processing/
You could use 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)
You can also use WPF/WIC by code, with a code like this (adapted from this article The fastest way to resize images from ASP.NET. And it’s (more) supported-ish.. You just need to add a reference to PresentationCore and WindowsBase which shouldn't be an issue for a desktop app.
// 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);
}
}
Otherwise there are lots of tools out there like MagicScaler, FreeImage ImageSharp, ImageMagick, Imazen, etc. Most were written for ASP.NET/Web server scenarios (for which WPF is officially not supported but works, read the article) and are also cross-platform which you don't seem to need. I'm not sure they're generally faster or use less memory than builtin Windows technology, but you should test all this in your context.
PS: otherwise there's no magic bullet, bigger images take more time.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With