我学习了图像处理,并从一些简单的事情开始,我写了一个程序将全色图像转换为黑白版本。在Windows窗体中对图像进行二进制化非常慢 - 为什么?
我使用C#和Windows窗体。我用PictureBox加载图像。然后我点击一个按钮来进行转换,这里是它的事件处理程序:
private void button1_Click(object sender, EventArgs e)
{
Color kolor, kolor_wynik;
byte r, g, b, avg, prog;
prog = 85;
int h = MainPictureBox.Height;
int w = MainPictureBox.Width;
Bitmap bitmap = new Bitmap(MainPictureBox.Image); //needed for GetPixel()
Graphics graphics = MainPictureBox.CreateGraphics();
for (int j = 0; j < h; j++)
{
for (int i = 0; i < w; i++)
{
kolor = bitmap.GetPixel(i, j);
r = kolor.R;
g = kolor.G;
b = kolor.B;
avg = (byte)((r + g + b)/3);
if (avg > prog)
kolor_wynik = Color.White;
else
kolor_wynik = Color.Black;
Pen pen = new Pen(kolor_wynik);
graphics.DrawEllipse(pen, i, j, 1, 1);
}
}
}
程序,它的工作,但问题是 - 这实在是太慢了。大约需要21秒将400x400图像转换为黑白图像。现在
,我就不会那么奇怪为什么,如果我不也有这样的计划写在VB 6.0:
Private Sub Command2_Click()
Dim kolor As Long ' kolor
Dim kolor_wynik As Long ' kolor
Dim r, g, b, avg As Byte
Dim prog As Byte
prog = 85
h = Picture1.ScaleHeight
w = Picture1.ScaleWidth
For j = 0 To h Step 1
For i = 0 To w Step 1
kolor = Picture1.Point(i, j)
r = kolor And &HFF
g = (kolor And &HFF00&)/&H100&
b = (kolor And &HFF0000)/&H10000
avg = (r + g + b)/3
If (avg > prog) Then
kolor_wynik = vbWhite
Else
kolor_wynik = vbBlack
End If
Picture1.PSet (i, j), kolor_wynik
Next i
Next j
End Sub
这两种算法都非常相似,但在VB 6.0版完成了这项工作几乎立即(我只能在Windows XP上测试它,而在Windows 10上则是C#版本)。
这种行为的原因是什么?我想用C#做东西,但事实证明必须切换到VB 6.0(这不是我想要做的)。
不是迭代像素,而是使用'Imaging.ColorMatrix'。黑色和白色通常不是什么人的意思 - 他们看起来很奇怪,像一个负面的。如果您的意思是灰度,请参阅:[将图像转换为灰度的更快方法](http://stackoverflow.com/a/23595488/1070452) – Plutonix
您是否尝试过使用[FillRectangle](https://msdn.microsoft.com/zh-cn/ -us/library/system.drawing.graphics.fillrectangle(v = vs.110).aspx)而不是'DrawEllipse'? – Pikoh
是的,Get/SetPixel由于锁定而无法执行,请参阅http://stackoverflow.com/questions/24701703/c-sharp-faster-alternatives-to-setpixel-and-getpixel-for-bitmaps-for-windows- f/http://stackoverflow.com/questions/1563038/fast-work-with-bitmaps-in-c-sharp –