1

Context:

Me and my colleagues work alot handling bitmap images via C#.

At the moment, we are also working with the AForge Framework for managing images, and since the methods of the AForge dll work with UnmanagedImage classes, we always need to convert a Bitmap to a UnmanagedImage before starting to use the library.

Simple Piece of Code:

This is how we usually convert the Bitmap to the UnmanagedImage Class

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

The problem is that we always have to do something like this in order to avoid exceptions:

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

Our Goal:

Avoid having to surround every piece of code with this try/finallystatement.

Is there any way we can aproach this in order to make it work ?

We've tried to Extend the bitmap, but since it's Sealed, it's not possible.

Also,writing extension methods such as this example would not work because it needs a static class to Be an Extension Handler and this would not help us in any ways.

Question:

That said, is there any way we can manage to Write a "Disposable" Bitmap when it comes to the "UnlockBits()" method, without having to write a "Wrapper" ?

By Wrapper i mean a class with a private bitmap attribute that would replicate calls to to the bitmap attribute. This would lead us to write every bitmap method again and just call the method with the same name on the private attribute, which is sort of Meh.

Thanks in advance

4

2 回答 2

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

}
于 2012-11-28T14:44:12.520 回答
1

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

于 2012-11-28T14:31:50.323 回答