有没有办法用C#编写一次性(解锁位)位图?

有没有办法用C#编写一次性(解锁位)位图?,c#,bitmap,idisposable,aforge,C#,Bitmap,Idisposable,Aforge,上下文: 我和我的同事经常通过C#处理位图图像 目前,我们还使用来管理图像,并且由于AForge dll的方法与类一起工作,因此在开始使用库之前,我们始终需要将位图转换为非托管图像 一段简单的代码: 这就是我们通常将位图转换为UnmanagedImage类的方式 BitmapData bmpData; Bitmap bmp = AForgeImaging.SetTo24BitsPerPixel(bmp); bmpData = bmp.Loc

上下文:

我和我的同事经常通过C#处理位图图像

目前,我们还使用来管理图像,并且由于AForge dll的方法与类一起工作,因此在开始使用库之前,我们始终需要将位图转换为非托管图像

一段简单的代码:

这就是我们通常将位图转换为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
语句包围每一段代码

我们有没有办法解决这个问题以使它发挥作用

我们试图扩展位图,但由于它是密封的,所以不可能

此外,编写扩展方法(如)将不起作用,因为它需要一个静态类
作为扩展处理程序
,这对我们没有任何帮助

问题:

也就是说,当涉及到“UnlockBits()”方法时,我们有没有办法编写“一次性”位图,而不必编写“包装器”

我所说的包装器是指具有
私有位图属性的类
复制对位图属性的调用。这将导致我们编写每个位图方法
再一次,只需在private属性上调用同名的方法,这有点像Meh


提前感谢

否。位图和位图数据都是密封的。您无法扩展它们,因此包装器是处理它的唯一(也是最好的)方法。

否。位图和位图数据都是密封的。您无法扩展它们,因此包装器是处理它们的唯一(也是最好的)方法。

您可以执行以下操作,在
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;
        }
    }

}

您可以执行以下操作,在
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;
        }
    }

}