无法获取地址,获取大小,或声明指向托管类型位图scan0的指针

时间:2012-02-18 12:18:58

标签: c# image

我定义了我自己的24位数据类型

class _24bit{
        public byte[] _value = new byte[3]; 
   }

我在_24位数据数组中有二进制数据

 _24bit  []data = new _24bit

我将我的位图声明为

Bitmap b = new Bitmap(columns / 3, rows, PixelFormat.Format24bppRgb);

但是当我声明这个在位图

中获取一行时
_24bit *row = (_24bit *)bmd.Scan0 + (j * bmd.Stride);

我收到此编译错误

不能获取地址,获取大小,或声明指向托管类型的指针('mynamespace._24bit')

如何继续使用自己的24位数据类型?

4 个答案:

答案 0 :(得分:1)

您实际上无法声明指向托管引用类型的指针(并且您的_24bit类是托管引用类型)。即使您将_24bit声明为struct(使其成为值类型),它仍然包含对字节数组的引用(不是字节数组本身,只是引用,这使得此结构的大小更大超过24位)。您可以将数组声明为fixedunsafe来解决此问题。您还可能需要指定StructLayout属性:

[StructLayout(LayoutKind.Sequential, Pack=1, Size=3)]
struct _24bpp
{
    public unsafe fixed byte _value[3];
}

请注意,您只能在unsafe上下文中访问此结构的内容。或者完全删除数组声明:

[StructLayout(LayoutKind.Sequential, Pack=1, Size=3)]
struct _24bpp
{
    public byte B;
    public byte G;
    public byte R;
}

或者,您可以根据数据结构重新创建位图,并将数据从非托管内存复制到数据结构。像

这样的东西
public static _24bit[][] GetBitmapPixelsFrom24bpp(BitmapData data)
{
    if(data == null) throw new ArgumentNullException("data");

    var bitmapRows = new _24bit[rows][];
    for(int row = 0; row < data.Height; ++r)
    {
        bitmapRows[row] = new _24bit[data.Width];
        for(int pixel = 0; pixel < data.Width; ++pixel)
        {
            byte b = Marshal.ReadByte(data.Scan0, data.Stride * row + pixel * 3 + 0);
            byte g = Marshal.ReadByte(data.Scan0, data.Stride * row + pixel * 3 + 1);
            byte r = Marshal.ReadByte(data.Scan0, data.Stride * row + pixel * 3 + 2);
            var bitmapPixel = new _24bit();
            bitmapPixel._value[0] = b;
            bitmapPixel._value[1] = g;
            bitmapPixel._value[2] = r;
            bitmapRows[row][pixel] = bitmapPixel;
        }
    }
    return bitmapRows;
}

答案 1 :(得分:0)

_24bit是一个托管引用类型,获取指向它的指针实际上是获取指向堆上某个非常量位置的引用的指针,这不是你想要的。

_24bit声明为struct而不是class,只要它只包含非托管类型,您就可以使用指针。它在this MSDN article中有更详细的解释。

struct _24bit
{
    public byte r, g, b;

    public byte this[int index]
    {
        switch (index)
        {
        case 0: return r;
        case 1: return g;
        case 2: return b;
        default: //throw exception or return 0 or something
        }
    }
}

答案 2 :(得分:0)

你不能像Robert G.写的那样初始化结构。

将您的结构放入初始化结构的类中。

答案 3 :(得分:0)

只需将您的班级重命名为

class bmp24bit()
{
    public byte[] _value = new byte[3]; 
}