【发布时间】:2016-11-16 16:53:07
【问题描述】:
我正在学习图像处理并从一些简单的东西开始,我编写了一个程序来将全彩色图像转换为它的黑白版本。
我使用了 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);
}
}
}
该程序完成了它的工作,但问题是 - 它真的很慢。将 400x400 图像转换为黑白大约需要 21 秒。
现在,如果我没有这个用 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 上测试它,而 C# 版本在 Windows 10 上测试)。
这种行为的原因是什么?我想在 C# 中做一些事情,但事实证明必须切换到 VB 6.0(这不是我想做的)。
【问题讨论】:
-
使用
Imaging.ColorMatrix,而不是迭代像素。黑白通常不是某人的意思——它们看起来很奇怪,就像一个负面的。如果您指的是灰度,请参阅:Faster method to Convert Image to grayscale -
你试过用FillRectangle代替
DrawEllipse吗? -
是的,Get/SetPixel 由于锁定而无法执行,请参阅stackoverflow.com/questions/24701703/… / stackoverflow.com/questions/1563038/…
-
要快速更改像素级别的图像,请查看LockBits。要进行简单的颜色更改,请查看ColorMatrix。
标签: c# winforms image-processing vb6