没有外部dll的图像负片的有效方法

这是一个解决方案,使C#Windows窗体中的图像没有任何dll并以有效,快速的方式产生负面影响?

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

只是添加一些时间细节:

在800万像素图像上执行取消(在2.4 Ghz Core 2 Duo上):

  • SetPixel(~22秒) – 慢220倍
  • Color Matrix,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); } } 

如果您有兴趣,这里是Color Matrix的代码:

  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 Settings\All Users\" + @"Documents\My Music\music.bmp", true); int x, y; // Loop through the images pixels to reset color. for(x=0; x