开发者

How to set the bits/pixels to a WriteableBitmap (with BlackWhite format (1bpp))

I am trying to create a binary image in C#/WPF using the WriteableBitmap class, with the BlackWhite Format which is 1 bit per pixel.

However, it seems the my image is very distorted when finished. Using different formats (such as brg32) works just fine. The pixel data is stored in a BitArray. The images vary from 1000x1000 to 3000x3000 pixels.

Here is the code I am current using:

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;
                开发者_C百科            *(byte*)(pBackBuffer + pixelOffset) = color;
                            color = 0;
                            colorOffset = 0;
                        }

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

As you can see, I am writing 8 pixels / bits , and then copying it to the back buffer. Perhaps someone who has a bit more knowledge in this topic could help. I've also tried directly copying the BitArray to a byte array, then copy the byte array to the backbuffer (and using the WritePixels function as well), both of which have not helped.

Regards, Dan


It seems like you are not using BackBufferStride property to compute address of the next line of pixels. Also note that you are missing some pixels if map width is not a multiple of 8. I didn't test the code, but i would have written it like this:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜