【问题标题】:What's the most efficient way to generate thumbnails?生成缩略图的最有效方法是什么?
【发布时间】:2012-11-10 23:24:17
【问题描述】:

我正在开发一个图形应用程序,我需要为每个页面保留一个缩略图。 挑战在于如何在不损失性能的情况下生成缩略图文件??

目前这是我的代码:

VisualBrush VisualBrush = new VisualBrush(pageToGenerateThumbnailFor);
UIVisual.Background = VisualBrush;

RenderTargetBitmap = new RenderTargetBitmap((int)UIVisual.ActualWidth, (int)UIVisual.ActualHeight, 96, 96, PixelFormats.Pbgra32);

rtb.Render(UIVisual);

using (FileStream outStream = new FileStream(ThumbFileFullPath, FileMode.OpenOrCreate, 
System.IO.FileAccess.ReadWrite))
{
   PngBitmapEncoder pngEncoder = new PngBitmapEncoder();
   pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
   pngEncoder.Save(outStream);
}

那么,有没有更快的方法来为给定的 Visual 生成缩略图?

谢谢

【问题讨论】:

  • 你有多少张图片,多久更换一次,等等?这些因素可能会影响正确答案
  • 查看imageresizing.net 以获得良好的解决方案,并查看nathanaeljones.com/blog/2009/20-image-resizing-pitfalls 以获得有关图像大小调整的一般信息
  • 图片的数量可能会有所不同,我不知道用户会如何使用它,但是,至于改变,它只是用户重新调整大小、旋转或移动图片的时候

标签: c# .net wpf thumbnails


【解决方案1】:

我最近做了一些研究,以便为电子商务网站即时生成图像缩略图。我开始自己生成位图,然后调整大小等,类似于上面的答案。在光盘上的图像大小和质量出现问题后,我查看了http://imageresizing.net/,此后我再也没有回头。它可以通过一行代码非常快速地从 byte()、流和物理文件生成图像:

ImageBuilder.Current.Build(New MemoryStream(bImage), sImageLocation + sFullFileName, New      ResizeSettings("maxwidth=214&maxheight=238"))

我肯定会推荐这个组件,而不是试图重新发明轮子......

【讨论】:

  • 这是一个Web应用程序的解决方案,但是,我们拥有的是一个桌面应用程序..
  • 嗨 Samir,这将在 WPF 应用程序中正常工作。我什至在预定的 Windows 服务上调用它。
【解决方案2】:

我编写的实用程序库中的以下类对我来说效果很好,并且可以生成清晰质量的缩略图...

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;

namespace Simple {
    public static class ThumbnailCreator {
        private static readonly object _lock = new object();

        public static Bitmap createThumbnail(Stream source, Int32 width, Int32 height) {
            Monitor.Enter(_lock);
            Bitmap output = null;
            try {
                using (Bitmap workingBitmap = new Bitmap(source)) {
                    // Determine scale based on requested height/width (this preserves aspect ratio)
                    Decimal scale;
                    if (((Decimal)workingBitmap.Width / (Decimal)width) > ((Decimal)workingBitmap.Height / (Decimal)height)) {
                        scale = (Decimal)workingBitmap.Width / (Decimal)width;
                    }
                    else {
                        scale = (Decimal)workingBitmap.Height / (Decimal)height;
                    }
                    // Calculate new height/width
                    Int32 newHeight = (Int32)((Decimal)workingBitmap.Height / scale);
                    Int32 newWidth = (Int32)((Decimal)workingBitmap.Width / scale);
                    // Create blank BitMap of appropriate size
                    output = new Bitmap(newWidth, newHeight, PixelFormat.Format32bppArgb);
                    // Create Graphics surface
                    using (Graphics g = Graphics.FromImage(output)) {
                        g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
                        g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                        Rectangle destRectangle = new Rectangle(0, 0, newWidth, newHeight);
                        // Use Graphics surface to draw resized BitMap to blank BitMap
                        g.DrawImage(workingBitmap, destRectangle, 0, 0, workingBitmap.Width, workingBitmap.Height, GraphicsUnit.Pixel);
                    }
                }
            }
            catch {
                output = null;
            }
            finally {
                Monitor.Exit(_lock);
            }
            return output;
        }
    }
}

它还保留了原始图像的纵横比。

【讨论】:

  • 天哪!这段代码看起来像是从 IL 中反编译的:P 当你有 lock 关键字时,为什么还要使用 Monitor.Enter 和 Exit?
猜你喜欢
  • 2021-07-13
  • 2011-06-08
  • 1970-01-01
  • 2012-12-24
  • 2012-01-21
  • 2011-08-12
  • 1970-01-01
  • 2011-04-12
  • 2019-11-17
相关资源
最近更新 更多