有没有办法在C#中编写Disposable(UnlockBits)位图?

时间:2012-11-28 14:27:51

标签: c# bitmap idisposable aforge

上下文

我和我的同事通过C#工作很多处理位图图像。

目前,我们还使用AForge Framework来管理图像,并且由于AForge dll的方法适用于UnmanagedImage类,我们总是需要先将Bitmap转换为UnmanagedImage开始使用图书馆。

简单的代码:

这就是我们通常将Bitmap转换为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()”方法中编写“Disposable”位图,而不必编写“Wrapper”?

By Wrapper我指的是一个private bitmap attribute的课程 复制对位图属性的调用。这将导致我们编写每个位图方法 再次,只需在私有属性上调用具有相同名称的方法,这是一种Meh。

提前致谢

2 个答案:

答案 0 :(得分: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 :(得分:1)

没有。 Bitmap和BitmapData都是密封的。你无法扩展它们,所以包装器是你处理它的唯一(也是最好的)方式。