我正在使用C#winforms项目中的“不安全”代码创建(然后更改)位图。这是每30ms左右完成的。我遇到的问题是“噪声”或随机像素有时会出现在生成的位图中,我没有特别改变任何东西。
例如,我创建了一个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;
在这个例子中,我只设置图像的左半部分(内部for循环中的Width / 2)。右半部分会在黑色背景上产生随机噪音。
答案 0 :(得分:5)
这有些推测,因为我不知道任何这些类的实现细节,但我猜错了。
当您调用new Bitmap(100, 100)
时,表示位图像素的内存区域未初始化,因此包含在分配之前这些内存位置中的随机垃圾。第一次写入位图时,您只设置了一个位置的子集,其他的则显示随机内存垃圾。
如果是这种情况,那么在第一次更新时,您必须确保在新Bitmap
中写入每个像素。后续更新只需更新已更改的像素。
答案 1 :(得分:3)
您需要在位图上创建一个图形对象,并在创建位图后进行Graphics.Clear()
调用,以避免位图内存的未定义状态。
您还应该从使用Format32bppRgb
更改为Format32PbppRgb
,因为您没有设置字母字节。要么是那么要么切换到24 bpp格式。