Невозможно получить адрес, получить размер или объявить указатель на управляемый тип растрового изображения scan0 - PullRequest
0 голосов
/ 18 февраля 2012

Я определил свой собственный 24-битный тип данных следующим образом

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

У меня есть данные в двоичном виде в массиве данных _24bit

 _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 ]

1 голос
/ 18 февраля 2012

Вы действительно не можете объявить указатели на управляемые ссылочные типы (а ваш класс _24bit является управляемым ссылочным типом).Даже если вы объявите _24bit как struct (сделав его типом значения), он все равно будет содержать ссылку на байтовый массив (не сам байтовый массив, а только ссылку, что делает размер этой структуры больше 24 бит),Вы можете объявить свой массив как fixed и unsafe, чтобы исправить это.Вам также может понадобиться указать атрибут 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;
}
0 голосов
/ 18 февраля 2012

Просто переименуйте свой класс в

class bmp24bit()
{
    public byte[] _value = new byte[3]; 
}
0 голосов
/ 18 февраля 2012

Вы не можете инициализировать структуру, как писал Роберт Г.

Поместите вашу структуру в класс, который инициализирует структуру.

0 голосов
/ 18 февраля 2012

_24bit является управляемым ссылочным типом, получение указателя на него по сути будет получением указателя на ссылку на какое-то непостоянное место в куче, а это не то, что вам нужно.

Объявите _24bit как struct вместо class, и вы сможете использовать с ним указатели, если они содержат только неуправляемые типы.Это объяснено более подробно в этой статье MSDN .

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
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...