2012-11-22 4 views
2

그래픽 응용 프로그램을 개발 중이며 각 페이지마다 미리보기 이미지를 유지해야합니다. 성능 저하없이 미리보기 이미지 파일을 생성하는 방법은 무엇입니까?축소판을 생성하는 가장 효율적인 방법은 무엇입니까?

현재 여기 내 코드는 그것을 할 수 있습니다 :

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); 
} 

그래서, 주어진 시각에 대한 썸네일을 생성하는 빠른 방법이 있나요?

감사

+0

얼마나 많은 이미지는 갖고 계신지, 얼마나 자주 바뀌는가 등? 이러한 요소는 정답에 영향을 미칠 가능성이 높습니다. –

+0

좋은 해결책은 http://imageresizing.net/을 참조하고 http://www.nathanaeljones.com/blog/2009/20-image-resizing-pitfalls에서 좋은 정보를 참조하십시오. 일반적으로 이미지 크기 조정 –

+0

이미지 개수는 다를 수 있습니다. 사용자가 이미지를 사용하는 방법은 모르지만 변경의 경우 사용자가 이미지의 크기를 변경하거나 회전하거나 이동할 때 – simo

답변

1

내가 나를 위해 잘 수행을 작성하고 좋은 명확한 품질의 축소판을 생성 한 유틸리티 라이브러리에서 다음 클래스 ...

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; 
     } 
    } 
} 

그것은 또한 원본 이미지의 가로 세로 비율을 유지합니다.

+0

오 맨! 이 코드는 IL에서 역 컴파일 된 것처럼 보입니다 : P'lock' 키워드가있을 때'Monitor.Enter'와'Exit'를 사용하는 이유는 무엇입니까? – khellang

+0

감사합니다. 성능을 테스트 했습니까? 최적화 되었습니까? – simo

2

저는 전자 상거래 사이트에서 바로 이미지 미리보기 이미지를 생성하기 위해 최근 약간의 연구를했습니다. 위의 대답과 유사하게 비트 맵을 생성 한 다음 크기를 조절하는 작업을 시작했습니다. 디스크와 품질의 이미지 크기에 문제가 생긴 후 나는 http://imageresizing.net/으로 보았고 이후로는 돌아 보지 않았습니다. 그것은, 스트림 및 신체 검사가 한 줄의 코드로 매우 신속하게 모든 파일) 바이트 (이미지를 생성 할 수 있습니다 ... 나는 확실히 바퀴를 재발견하는 것보다이 구성 요소를 오히려 추천 할 것입니다

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

+0

이것은 웹 응용 프로그램을위한 솔루션이지만, 우리가 가진 것은 데스크톱 응용 프로그램입니다. – simo

+0

안녕 사미르,이 문제없이 WPF 응용 프로그램에서 작동합니다. 심지어는 예약 된 Windows 서비스에서 호출합니다. – James

관련 문제