2012-11-28 2 views
1

상황 :C#에서 일회용 (UnlockBits) 비트 맵을 쓸 수있는 방법이 있습니까?

은 나와 내 동료들은 많이 C#을 통해 비트 맵 이미지를 처리하는 작업. 순간

, 우리는 또한 이미지를 관리하기위한 AForge Framework로 작업하고, UnmanagedImage 클래스와 AForge DLL을 작업의 방법부터, 우리는 항상 라이브러리를 사용하기 시작하기 전에 UnmanagedImage에 비트 맵 변환해야합니다.

는 코드의

간단한 조각 :

이것은 우리가 일반적으로 우리가 항상 피하기 위해 같은 것을 할 필요가 있다는 것입니다 UnmanagedImage 클래스

 BitmapData bmpData; 
     Bitmap bmp = AForgeImaging.SetTo24BitsPerPixel(bmp); 
     bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); 

     UnmanagedImage unmanaged = new UnmanagedImage(bmpData); 

문제에 비트 맵 변환하는 방법입니다 예외 :

 try 
     { 
      // Create Unmanaged Image 
      // Process the Image And Stuff 
     } 
     finally 
     { 
      // Unlock BitmapBits 
     } 

우리의 목표 :

코드의 모든 부분을이 try/finally 문으로 묶지 않아도됩니다.

작동시키기 위해이 문제를 해결할 수있는 방법이 있습니까?

우리는 비트 맵 Extend을 시도했지만, 봉인되었으므로 불가능합니다.

this example과 같은 작성 확장 프로그램은 작동하지 않습니다. 정적 클래스가 Be an Extension Handler이어야하며 어떤 방식 으로든 도움이되지 않습니다.

질문 : 말했다

, 우리는 "UnlockBits()"방법에 관해서는 "래퍼"를 작성하지 않고 "일회용"비트 맵을 작성 관리 할 수있는 방법이있다?

래퍼는 private bitmap attribute 인 클래스를 말하며 은 비트 맵 속성에 대한 호출을 복제합니다. 이렇게하면 모든 비트 맵 메서드 을 다시 작성하고 개인 속성 인 Meh와 같은 이름의 메서드를 호출 할 수 있습니다.

미리 감사드립니다.

답변

4

누락 된 속성을 Scan0 등과 같이 추가하면 다음과 같이 할 수 있습니다. 그런 다음이를 사용하는 기존 코드를 변경할 필요가 없습니다.

using System; 
using System.Drawing; 
using System.Drawing.Imaging; 
static class Program 
{ 

    static void Main() 
    { 

     Bitmap bmp = new Bitmap(100, 100); 

     using (var bmpData = bmp.SmartLock(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat)) 
     { 
      // use Scan0 etc as normal 
     } 
    } 
} 
static class BitmapUtils 
{ 
    public static WrappedBitmapData SmartLock(this Bitmap bitmap, Rectangle rect, ImageLockMode flags, PixelFormat format) 
    { 
     return new WrappedBitmapData(bitmap, bitmap.LockBits(rect, flags, format)); 
    } 
    public class WrappedBitmapData : IDisposable 
    { 
     public int Height { get { return data.Height; } } 
     public int Width { get { return data.Width; } } 
     public IntPtr Scan0 { get { return data.Scan0; } } 
     public PixelFormat PixelFormat { get { return data.PixelFormat; } } 
     // etc here ^^^ TODO 
     internal WrappedBitmapData(Bitmap bmp, BitmapData data) 
     { 
      this.bmp = bmp; 
      this.data = data; 
     } 
     private Bitmap bmp; 
     private BitmapData data; 
     public void Dispose() 
     { 
      if (data != null && bmp != null) 
      { 
       bmp.UnlockBits(data); 
      } 
      data = null; 
      bmp = null; 
     } 
    } 

} 
1

아니요. 비트 맵과 BitmapData는 모두 봉인되어 있습니다. 그것들을 확장 할 수 없기 때문에 래퍼가이를 처리하는 유일한 방법입니다.

관련 문제