如何避免“噪音”在不安全代码中设置图像像素时

本文关键字:设置 图像 像素 代码 不安全 何避免 噪音 | 更新日期: 2023-09-27 17:50:09

我正在c# winforms项目中使用"不安全"代码创建(然后更改)位图。这大约每30毫秒进行一次。我遇到的问题是,"噪音"或随机像素有时会出现在我没有特别改变任何东西的结果位图中。

例如,我创建了一个100x100的位图。使用BitmapDataLockBits,我遍历位图并将某些像素更改为特定颜色。然后我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;

在这个例子中,我只设置了图像的左半部分(在内部for循环中Width/2)。右半部分为随机杂色,背景为黑色

如何避免“噪音”在不安全代码中设置图像像素时

这有点投机,因为我不知道这些类的实现细节,但我有一个猜测。

当您调用new Bitmap(100, 100)时,表示位图像素的内存区域是未初始化的,因此包含分配之前在这些内存位置中的任何随机垃圾。第一次写入位图时,您只设置了位置的一个子集,其他位置显示随机内存垃圾。

如果是这种情况,那么您必须确保在第一次更新新Bitmap时写入中的每个像素。后续更新只需要更新更改的像素

您需要在位图上创建一个图形对象,并在创建位图后放置Graphics.Clear()调用,以避免位图内存的未定义状态。

您还应该从使用Format32bppRgb更改为Format32PbppRgb,因为您没有设置alpha字节。或者切换到24bpp格式