Как установить биты / пиксели в WriteableBitmap (с форматом BlackWhite (1bpp)) - PullRequest
1 голос
/ 19 марта 2011

Я пытаюсь создать двоичное изображение в C # / WPF с использованием класса WriteableBitmap с форматом BlackWhite, равным 1 биту на пиксель.

Тем не менее, кажется, что мое изображение очень искажено, когда закончите. Использование разных форматов (например, brg32) работает просто отлично. Данные пикселей хранятся в BitArray. Размер изображения варьируется от 1000x1000 до 3000x3000 пикселей.

Вот код, который я сейчас использую:

unsafe
            {
                int colorOffset = 0;
                int pixelOffset = 0;
                byte color = 0;
                int pBackBuffer = (int)_image.BackBuffer;

                for (int y = 0; y < mapData.Height; y++)
                {
                    for (int x = 0; x < mapData.Width; x++)
                    {

                        if (mapData.Data[y * mapData.Height + x])
                        {
                            //Set the pixel to white
                            color += 1;
                        }

                        //Shift the pixel position by 1
                        color = (byte)(color << 1);

                        //If 8 pixels have been written, write it to the backbuffer
                        if (++colorOffset == 8)
                        {
                            pixelOffset = ((y * mapData.Height) + x) / 8;
                            *(byte*)(pBackBuffer + pixelOffset) = color;
                            color = 0;
                            colorOffset = 0;
                        }

                    }
                }
                //Update the image
                _image.AddDirtyRect(new Int32Rect(0, 0, mapData.Width, mapData.Height));
            }

Как видите, я пишу 8 пикселей / бит, а затем копирую его в задний буфер. Возможно, кто-то, кто имеет немного больше знаний в этой теме, мог бы помочь. Я также попытался напрямую скопировать BitArray в байтовый массив, а затем скопировать байтовый массив в буфер (и также с помощью функции WritePixels), которые не помогли.

С уважением, Dan

1 Ответ

1 голос
/ 19 марта 2011

Похоже, вы не используете свойство BackBufferStride для вычисления адреса следующей строки пикселей.Также обратите внимание, что вам не хватает нескольких пикселей, если ширина карты не кратна 8. Я не тестировал код, но написал бы его так:

unsafe
{
    int colorOffset = 0;
    int pixelOffset = 0;
    byte color = 0;
    byte* pBackBuffer = (byte*)_image.BackBuffer;
    for(int y = 0; y < mapData.Height; y++)
    {
        // get a pointer to first pixel in a line y
        byte* pixLine = pBackBuffer;
        for(int x = 0; x < mapData.Width; x++)
        {

            // fix #1: offset = y * width + x, not y * height + x
            var mapOffset = y * mapData.Width + x;

            if (mapData.Data[mapOffset])
            {
                //Set the pixel to white
                color += 1;
            }

            //Shift the pixel position by 1
            color = (byte)(color << 1);

            //If 8 pixels have been written, write it to the backbuffer
            if(++colorOffset == 8)
            {
                *pixLine++ = color;
                color = 0;
                colorOffset = 0;
            }

        }
        // fix #2: copy any pixels left
        if(colorOffset != 0)
        {
            *pixLine++ = color;
            colorOffset = 0;
            color = 0;
        }

        // fix #3: next line offset = previous line + stride, they are aligned
        pBackBuffer += _image.BackBufferStride;
    }
    //Update the image
    _image.AddDirtyRect(new Int32Rect(0, 0, mapData.Width, mapData.Height));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...