没有外部dll的图像阴性的有效方式

这是在C#Windows窗体中使用没有任何dll并且以有效,快速的方式对图像进行否定的解决方案?


最好的方法是直接用位图数据访问像素。

只需添加一些时间细节:

对800万像素图像执行反转操作(在2.4 Ghz Core 2 Duo上):

  • SetPixel(〜22秒) - 慢了220倍
  • 彩色矩阵,Matajon的方法低于(〜750毫秒) - 慢7倍
  • 直接访问位图数据(〜100毫秒) - 最快
  • 所以,如果你不能有不安全的代码,那么Color Matrix比SetPixel好得多。

        public static void Negate(Bitmap image)
        {
            const int RED_PIXEL = 2;
            const int GREEN_PIXEL = 1;
            const int BLUE_PIXEL = 0;
    
    
            BitmapData bmData = currentImage.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat);
    
            try
            {
                int stride = bmData.Stride;
                int bytesPerPixel = (currentImage.PixelFormat == PixelFormat.Format24bppRgb ? 3 : 4);
    
                unsafe
                {
                    byte* pixel = (byte*)(void*)bmData.Scan0;
                    int yMax = image.Height;
                    int xMax = image.Width;
    
                    for (int y = 0; y < yMax; y++)
                    {
                        int yPos = y * stride;
                        for (int x = areaSize.X; x < xMax; x++)
                        {
                            int pos = yPos + (x * bytesPerPixel);
    
                            pixel[pos + RED_PIXEL] = (byte)(255 - pixel[pos + RED_PIXEL]);
                            pixel[pos + GREEN_PIXEL] = (byte)(255 - pixel[pos + GREEN_PIXEL]);
                            pixel[pos + BLUE_PIXEL] = (byte)(255 - pixel[pos + BLUE_PIXEL]);                                                    
                        }
    
                    }
                }
            }
            finally
            {
                image.UnlockBits(bmData);
            }
    
        }
    

    如果你有兴趣,这里是彩色矩阵的代码:

        public static void Negate(Bitmap image)
        {
    
                Bitmap clone = (Bitmap) image.Clone();
    
                using (Graphics g = Graphics.FromImage(image))
                {
    
                    // negation ColorMatrix
                    ColorMatrix colorMatrix = new 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[] {0, 0, 0, 0, 1}
                            });
    
                    ImageAttributes attributes = new ImageAttributes();
    
                    attributes.SetColorMatrix(colorMatrix);
    
                    g.DrawImage(clone, new Rectangle(0, 0, clone.Width, clone.Height),
                                0, 0, clone.Width, clone.Height, GraphicsUnit.Pixel, attributes);
               }
        }
    

    逐个浏览所有像素(Bitmap.GetPixel()或其他)并从0xff中减去RGB值以创建负像素。 使用(Bitmap.SetPixel())将此像素保存到新图像或同一位置上的同一图像上。

        // Retrieve the image.
        var image1 = new Bitmap(@"C:Documents and SettingsAll Users" 
            + @"DocumentsMy Musicmusic.bmp", true);
    
        int x, y;
    
        // Loop through the images pixels to reset color.
        for(x=0; x<image1.Width; x++)
        {
            for(y=0; y<image1.Height; y++)
            {
                Color pixelColor = image1.GetPixel(x, y);
                Color newColor = Color.FromArgb(0xff - pixelColor.R
                , 0xff - pixelColor.G, 0xff - pixelColor.B);
                image1.SetPixel(x, y, newColor);
            }
        }
    
    链接地址: http://www.djcxy.com/p/52901.html

    上一篇: Effective way of making negative of image without external dlls

    下一篇: Widget under a QTabBar with unwanted frame