彩色反转性能提升Tiff图像- c#

本文关键字:Tiff 图像 性能 彩色 | 更新日期: 2023-09-27 18:17:08

我用的是Winforms。在我的表单中,我有一个图片框,我加载tiff文档。我使用下面的代码在按钮单击时在文档中来回反转颜色。我的代码的问题是,它是非常缓慢的。如何更快地转换图像的颜色?

图片信息:

  • 图片尺寸:8.5 x 11英寸
  • 像素密度:300 × 300像素/英寸
  • 像素尺寸- 2550 x 3300像素(通常是因为我打开不同的文档来查看)

    private void button1_Click(object sender, 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;
    }
    

彩色反转性能提升Tiff图像- c#

由于太多原因,GetPixel和SetPixel确实很慢。此外,嵌套循环通常也是一个坏主意。看看下面的链接,可以获得一些更快的实现(不是最优的,但更接近)

http://www.codeproject.com/Articles/1989/Image-Processing-for-Dummies-with-C-and-GDI-Part

它涉及使用不安全代码和图像的LockPixel方法。

链接中的代码(您需要在项目设置中允许不安全代码)

public static bool Invert(Bitmap b)
{
    // GDI+ still lies to us - the return format is BGR, NOT RGB. 
    BitmapData bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), 
    ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 
    int stride = bmData.Stride; 
    System.IntPtr Scan0 = bmData.Scan0; 
    unsafe 
    { 
        byte * p = (byte *)(void *)Scan0;
        int nOffset = stride - b.Width*3; 
        int nWidth = b.Width * 3;
        for(int y=0;y < b.Height;++y)
        {
            for(int x=0; x < nWidth; ++x )
            {
                p[0] = (byte)(255-p[0]);
                ++p;
            }
            p += nOffset;
        }
    }
    b.UnlockBits(bmData);
    return true;
}

如果这段代码不工作,因为你有不同的图像格式,那么你需要修改一些部分,在像素的大小方面。(例子中的常量是3)您可以通过以下方式计算得到它:

int pixelSize = imageData.Stride/image.Width;

和替换

PixelFormat.Format24bppRgb 

b.PixelFormat

看一下这个问题:

反转图像返回黑色图像

Dan在他的解决方案中使用了带有图像属性的颜色矩阵。

下面是你如何使用它(未经测试):

声明你的颜色矩阵,这样你就不必每次都重新定义它了:

    System.Drawing.Imaging.ColorMatrix m_colorMatrix;
    private void Init()
    {
        // create the negative color matrix
        m_colorMatrix = new System.Drawing.Imaging.ColorMatrix(new float[][] {
            new float[] {-1, 0, 0, 0, 0},
            new float[] {0, -1, 0, 0, 0},
            new float[] {0, 0, -1, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {1, 1, 1, 0, 1}
        });
    }

现在,在按钮单击事件中,提供图片框控件:

    private void Button_Click(object sender, EventArgs e) {
        var source = new Bitmap(pictureBox1.Image);
        //create a blank bitmap the same size as original
        var bmpInvert = new Bitmap(source.Width, source.Height);
        //get a graphics object from the new image
        using (var g = Graphics.FromImage(bmpInvert))
        {
            // create some image attributes
            var attributes = new System.Drawing.Imaging.ImageAttributes();
            attributes.SetColorMatrix(m_colorMatrix);
            g.DrawImage(source, new Rectangle(0, 0, source.Width, source.Height),
                        0, 0, source.Width, source.Height, GraphicsUnit.Pixel, attributes);
            pictureBox1.Image = bmpInvert;
        }
    }

由于我在使用块中包含了Graphics对象is,因此您不应该像他那样调用Dispose方法。

这可能会得到你需要的东西,但我没有任何东西可以测试。