C #, новый Bitmap с IntPtr, ArgumentException - PullRequest
2 голосов
/ 26 мая 2011

У меня очень странная проблема.

Вот мой упрощенный код для объяснения:

class Bitmap1
{
    public Bitmap nImage;
    public IntPtr data;


    public Bitmap1()
    {
        int w = 2450;
        int h = 2450;

        this.data = Marshal.AllocHGlobal(w*h);

        nImage = new Bitmap(w, h, w, PixelFormat.Format8bppIndexed, data);

    }
}

Когда w и h равны 2448 , все работает хорошо, если я вызываю конструктор.

Но когда h и w равны 2450 , у меня есть ArgumentException, который, кажется, запускается по "новому растровому изображению (...);"

Я не могу понять, и в документации не сказано, что есть ограниченный размер для Marshal.AllocHGlobal.

Что не так? Есть ли другие способы сделать то, что я хочу?

Большое спасибо.

Ответы [ 2 ]

5 голосов
/ 26 мая 2011

stride Тип: System.Int32 Целое число, которое указывает смещение байта между началом одной строки сканирования и следующей.Обычно это (но не обязательно) количество байтов в формате пикселей (например, 2 на 16 бит на пиксель), умноженное на ширину растрового изображения. Значение, передаваемое этому параметру, должно быть кратно четырем ..

http://msdn.microsoft.com/en-us/library/zy1a2d14.aspx

Поэтому вам нужно что-то вроде следующего:

int w = 2450;
int h = 2450;
int s = 2452;//Next multiple of 4 after w

this.data = Marshal.AllocHGlobal(s*h);

nImage = new Bitmap(w, h, s, PixelFormat.Format8bppIndexed, data);

Это означает, что есть 2 байта между каждой строкой, которая просто дополняет и не является частью самого растрового изображения.При выполнении арифметики с указателями вам, очевидно, нужно учитывать s*y+x, а не w*y+x для учета заполнения.

1 голос
/ 26 мая 2011
Bitmap bmp = new Bitmap("SomeImage");

// Lock the bitmap's bits.  
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite,
                                  PixelFormat.Format24bppRgb);

// Get the address of the first line.
IntPtr ptr = bmpData.Scan0;

// Declare an array to hold the bytes of the bitmap.
int bytes = bmpData.Stride * bmp.Height;
byte[] rgbValues = new byte[bytes];

// Copy the RGB values into the array.
Marshal.Copy(ptr, rgbValues, 0, bytes);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...