在C#中更快地反转图像

5

我正在使用WinForms。 我的表单中有一个图片框。 当我在图片框中打开一张图片时,我可以通过单击按钮来反转颜色,但我的代码非常缓慢。 如何提高性能。

   private void Button1_Click(object sender, System.EventArgs e) 
     {
        Bitmap pic = new Bitmap(PictureBox1.Image);
        for (int y = 0; (y 
                    <= (pic.Height - 1)); y++) {
            for (int x = 0; (x 
                        <= (pic.Width - 1)); x++) {
                Color inv = pic.GetPixel(x, y);
                inv = Color.FromArgb(255, (255 - inv.R), (255 - inv.G), (255 - inv.B));
                pic.SetPixel(x, y, inv);
                PictureBox1.Image = pic;
            }

        }

    }
3个回答

16
每次更改像素时,您都会设置控件的图片,这会导致控件重新绘制。请等到您完成图像再进行设置:
Bitmap pic = new Bitmap(PictureBox1.Image);
for (int y = 0; (y <= (pic.Height - 1)); y++) {
    for (int x = 0; (x <= (pic.Width - 1)); x++) {
        Color inv = pic.GetPixel(x, y);
        inv = Color.FromArgb(inv.A, (255 - inv.R), (255 - inv.G), (255 - inv.B));
        pic.SetPixel(x, y, inv);
    }
}
PictureBox1.Image = pic;

@D Stanley,感谢您的解释和示例。它完美地起作用了。 - taji01
5
Get/SetPixel速度非常慢。搜索LockBits并使用它-您可以获得快几个数量级的结果。 - Lucas Trzesniewski
@LucasTrzesniewski 我会研究一下的。不过在这种情况下如何使用 LockBits 我并不是很熟悉。如果您能给出一个例子,我会非常感激。 - taji01
1
@taji01,在这个网站上关于这个主题的问题数不胜数,只要搜索一下,您会找到比您期望的还要多的答案 ;) - Lucas Trzesniewski
我找到了一些,但我不知道如何像我现在这样将其合并到按钮点击中。@LucasTrzesniewski - user5072189
这是一个糟糕的例子!- 不要使用!! - TaW

0
改进 D Stanley 的建议,避免将图像转换为位图然后重新分配造成的内存和处理负担,实际上可以通过直接获取和设置 PictureBox 的 .Image 上的像素来进行操作,只需将其强制转换并调用相关的位图操作函数即可:
private void Button1_Click(object sender, System.EventArgs e) 
 {
    for (int y = 0; (y 
                <= (PictureBox1.Image.Height - 1)); y++) {
        for (int x = 0; (x 
                    <= (PictureBox1.Image.Width - 1)); x++) {
            Color inv = ((Bitmap)PictureBox1.Image).GetPixel(x, y);
            inv = Color.FromArgb(255, (255 - inv.R), (255 - inv.G), (255 - inv.B));
            ((Bitmap)PictureBox1.Image).SetPixel(x, y, inv);

        }

    }
}

-2
如果有人需要VB.NET中类似的代码,请参考以下内容。
另外注意变量inv.A而非数值255。如果您的picturebox具有透明度,则需要这样做。
    Public Function InvertImageColors(ByVal p As Image) As Image
        Dim pic As New Bitmap(p)
        For y As Integer = 0 To pic.Height - 1
            For x As Integer = 0 To pic.Width - 1
                Dim inv As Color = pic.GetPixel(x, y)
                inv = Color.FromArgb(inv.A, 255 - inv.R, 255 - inv.G, 255 - inv.B)
                pic.SetPixel(x, y, inv)
            Next x
        Next y
        Return pic
    End Function

使用方法:

    pic.image = InvertImageColors(pic.image)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接