Как избежать «шума» при настройке пикселей изображения в небезопасном коде - PullRequest
5 голосов
/ 15 апреля 2011

Я создаю (затем изменяю) растровое изображение, используя «небезопасный» код в проекте winforms C #.Это делается каждые 30 мс или около того.У меня проблема в том, что в результирующем растровом изображении иногда появляются «шум» или случайные пиксели, где я ничего специально не менял.

Например, я создаю растровое изображение 100x100.Используя BitmapData и LockBits, я перебираю растровое изображение и меняю определенные пиксели на определенный цвет.Затем я UnlockBits и установить картинку для использования изображения.Все пиксели, которые я установил, правильные, но пиксели, которые я специально не устанавливал, иногда кажутся случайными цветами.

Если я установлю каждый пиксель, шум исчезнет.Однако по соображениям производительности я бы предпочел установить только минимальное число.

Может кто-нибудь объяснить, почему это происходит?

Вот пример кода:

// 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;

В этом примере я устанавливаю только левую половину изображения (ширина / 2 во внутреннем цикле for).Правая половина будет иметь случайный шум на черном фоне.

Ответы [ 2 ]

5 голосов
/ 15 апреля 2011

Это несколько умозрительно, так как я не знаком с деталями реализации любого из этих классов, но у меня есть предположение.

Когда вы вызываете new Bitmap(100, 100), область памяти, которая представляет пиксели растрового изображения, является неинициализированной и, следовательно, содержит любой случайный мусор, который был в этих местах памяти до его выделения. Когда вы впервые записываете в растровое изображение, вы устанавливаете только подмножество местоположений, а остальные показывают случайный мусор памяти.

Если это так, то при первом обновлении Bitmap необходимо обязательно писать в каждый пиксель в новом *1010*. Последующие обновления требуют обновления только измененных пикселей.

3 голосов
/ 15 апреля 2011

Вам потребуется создать графический объект поверх растрового изображения и выполнить вызов Graphics.Clear() после создания растрового изображения, чтобы избежать неопределенного состояния памяти растрового изображения.

Вам также следует перейти от использования Format32bppRgb до Format32PbppRgb, потому что вы не устанавливаете альфа-байт.Либо так, либо переключитесь на формат 24 бит / с.

...