开发者

How to avoid "noise" when setting pixels of image in unsafe code

I am creating (then altering) a bitmap using "unsafe" code in a C# winforms project. This is done every 30ms or so. The problem I'm having is that "noise" or random pixels will show up sometimes in the resulting bitmap where I did not specifically change anything.

For example, I create a bitmap of 100x100. Using BitmapData and LockBits, I iterate through the bitmap and change certain pixels to a specific color. Then I UnlockBits and set a picturebox to use the image. All of the pixels I set are correct, but pixels that I did not specifically set are sometimes seemingly random colors.

If I set every pixel, the noise disappears. However, for performance reasons, I would prefer only to set the minimum number.

Can anyone explain why it does this?

Here is some example code:

// Create new output bitmap
Bitmap Output_Bitmap = new Bitmap(100, 100);

// Lock the output bitmap's bits
Rectangle Output_Rectangle = new Rectangle(
    0,
    0,
    Output_Bitmap.Width,
    Output_Bitmap.Height);
BitmapData Output_Data = Output_Bitmap.LockBits(
    Output_Rectangle,
    ImageLockMode.WriteOnly,
    PixelFormat.Format32bppRgb);

const int PixelSize = 4;
unsafe
{
    for (int y = 0; y < Output_Bitmap.Height; y++)
    {
        for (int x = 0; x < Output_Bitmap.Width/2; x++)
        {
            Byte* Output_Row = (Byte*)Output_Data.Scan0 + y * Output_Data.Stride;
            Output_Row[(x * PixelSize) + 2] = 255;
            Output_Row[(x * PixelSize) + 1] = 0;
            Output_Row[(x * PixelSize) + 0] = 0;
        }
    }
}

// Unlock the bits
Output_Bitmap.UnlockBits(Output_Data);

// Set picturebox to use bitmap
p开发者_如何学运维bOutput.Image = Output_Bitmap;

In this example, I am only setting the left half of the image (Width/2 in the inner for loop). The right half will have random noise on an otherwise black background.


This is somewhat speculative, since I'm not privy to the implementation details of any of these classes, but I have a guess.

When you call new Bitmap(100, 100), the memory region that represents the bitmap's pixels is uninitialized, and therefore contains whatever random garbage was in those memory locations before it was allocated. The first time that you write to the bitmap you then set a only a subset of the locations, and the others show the random memory garbage.

If this is the case, then you must be sure to write to every pixel in the new Bitmap the first time you update it. Subsequent updates only need to update the changed pixels.


You'll need to create a graphics object over the bitmap and place a Graphics.Clear() call after you create your bitmap to avoid undefined state of the bitmap memory.

You should also change from using Format32bppRgb to Format32PbppRgb because you're not setting the alpha byte. Either that or switch to the 24 bpp format.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜