Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
pbOutput.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.

like image 500
JYelton Avatar asked Apr 14 '11 20:04

JYelton


1 Answers

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.

like image 85
JSBձոգչ Avatar answered Sep 21 '22 10:09

JSBձոգչ