如何在 C# 中以像素级别操作图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/190385/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:22:46  来源:igfitidea点击:

How to manipulate images at the pixel level in C#

c#image-processingimage-manipulation

提问by Kamil Zadora

How do I manipulate images at the pixel level in C#?

如何在 C# 中以像素级别操作图像?

I need to be able to read/modify each bitmap pixel RGB values separately.

我需要能够分别读取/修改每个位图像素 RGB 值。

A code sample would be appreciated.

代码示例将不胜感激。

采纳答案by Marc Gravell

If you want speed, then LockBits. See here for a good walkthrough by Bob Powell. If you just want to edit a few, then GetPixel/SetPixelshould do what you want.

如果你想要速度,那么LockBits请参阅此处查看 Bob Powell 的精彩演练。如果你只是想编辑一些,那么GetPixel/ SetPixel应该做你想做的。

回答by Grank

System.Drawing.Bitmap has a GetPixel(int x, int y) public method that returns a System.Drawing.Color structure. That struct has byte members R, G, B, and A, which you can modify directly, and then call SetPixel(Color) on your Bitmap again.
Unfortunately, that's going to be relatively slow, but it's by the easiest way to do it in C#. If you are working with individual pixels a lot and find the performance is lacking, and you need something faster, you can use LockBits... It's a lot more complicated though, as you need to understand the bit structure for that color depth and type, and work with the bitmap's stride and what not... so if you find it's necessary, make sure you find a good tutorial! There are several out there on the web, Googling "C# LockBits" will get you a half dozen that are worth a read.

System.Drawing.Bitmap 有一个 GetPixel(int x, int y) 公共方法,它返回一个 System.Drawing.Color 结构。该结构具有字节成员 R、G、B 和 A,您可以直接修改它们,然后再次在您的位图上调用 SetPixel(Color)。
不幸的是,这会相对较慢,但这是在 C# 中最简单的方法。如果您经常使用单个像素并发现性能不足,并且您需要更快的速度,则可以使用 LockBits...虽然它要复杂得多,因为您需要了解该颜色深度和类型的位结构,并使用位图的步幅以及其他什么……所以如果您觉得有必要,请确保找到一个好的教程!网上有几个,谷歌搜索“C# LockBits”

回答by mattlant

A sample code routine (I use this for simple merge and compare functionality. It takes two images and produces a third greyscale image showing the differences between the two images as a greyscale tone level. The darker it is, the more the diff.):

示例代码例程(我将其用于简单的合并和比较功能。它需要两个图像并生成第三个灰度图像,将两个图像之间的差异显示为灰度色调级别。颜色越暗,差异越大。):

    public static Bitmap Diff(Bitmap src1, Bitmap src2, int x1, int y1, int x2, int y2, int width, int height)
{
    Bitmap diffBM = new Bitmap(width, height, PixelFormat.Format24bppRgb);

    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            //Get Both Colours at the pixel point
            Color col1 = src1.GetPixel(x1 + x, y1 + y);
            Color col2 = src2.GetPixel(x2 + x, y2 + y);

            // Get the difference RGB
            int r = 0, g = 0, b = 0;
            r = Math.Abs(col1.R - col2.R);
            g = Math.Abs(col1.G - col2.G);
            b = Math.Abs(col1.B - col2.B);

            // Invert the difference average
            int dif = 255 - ((r+g+b) / 3);

            // Create new grayscale RGB colour
            Color newcol = Color.FromArgb(dif, dif, dif);

            diffBM.SetPixel(x, y, newcol);

        }
    }

    return diffBM;
}

Marc's postnotes LockBits and using that to modify the image directly in memory. I would suggest looking at that rather than what I have posted if performance is a concern. Thanks Marc!

Marc 的帖子记录了 LockBits 并使用它直接在内存中修改图像。如果性能是一个问题,我建议查看它而不是我发布的内容。谢谢马克!

回答by Ash

If performance is critical, another alternative to LockBits is managed DirectX.

如果性能至关重要,则 LockBits 的另一个替代方案是托管 DirectX。

See the earlier Stack Overflow question Rendering graphics in C#for more information.

有关详细信息,请参阅较早的 Stack Overflow 问题在 C# 中渲染图形

Like Lockbits you will need to use the unsafe keyword/compiler switch, but you get high performance pixel level access.

与 Lockbits 一样,您将需要使用 unsafe 关键字/编译器开关,但您可以获得高性能像素级访问。

You also get higher performance screen rendering via DirectX backbuffering, when compared with using the normal Bitmap class and PictureBox control.

与使用普通 Bitmap 类和 PictureBox 控件相比,您还可以通过 DirectX 后台缓冲获得更高性能的屏幕渲染。