制作负片时间长
Long time for making negative photo
这种方法比普通的图片编辑器处理时间长,为什么?
public Image InvertColor(Image img)
{
Bitmap bmp = new Bitmap(img);
for (int i = 0; i < bmp.Width; i++)
{
for (int j = 0; j < bmp.Height; j++)
{
bmp.SetPixel(i, j,
Color.FromArgb(
byte.MaxValue - bmp.GetPixel(i, j).R,
byte.MaxValue - bmp.GetPixel(i, j).G,
byte.MaxValue - bmp.GetPixel(i, j).B));
}
}
return (Image)bmp;
}
那是因为 GetPixel
和 SetPixel
方法很慢。不是很慢,但是因为你进行了很多次调用,开销加起来了。
您可以从每个像素只调用一次 GetPixel
而不是三次开始:
public Image InvertColor(Image img) {
Bitmap bmp = new Bitmap(img);
for (int i = 0; i < bmp.Width; i++) {
for (int j = 0; j < bmp.Height; j++) {
Color source = bmp.GetPixel(i, j);
bmp.SetPixel(i, j,
Color.FromArgb(
byte.MaxValue - source.R,
byte.MaxValue - source.G,
byte.MaxValue - source.B
)
);
}
}
return (Image)bmp;
}
这应该使它快两倍。为了更快地获得它,您需要直接访问图像数据。您可以使用 LockBits
method 获取指向图像数据的指针。
这是最快的方法。它使用 ColorMatrix
并且基本上不花时间,即使对于大 Images
.
private Image fastInvert(Image img)
{
float[][] cm = 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}
};
ColorMatrix CM = new ColorMatrix(cm);
ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(CM);
using ( Graphics g = Graphics.FromImage(img) )
g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0,
img.Width, img.Height, GraphicsUnit.Pixel, ia);
return img;
}
矩阵数据是 Visual Kicks, who get it right, as opposed to any other site I found, including Bob Powell's 的荣誉,它的更新真的是 hack,甚至对我都不起作用..
这种方法比普通的图片编辑器处理时间长,为什么?
public Image InvertColor(Image img)
{
Bitmap bmp = new Bitmap(img);
for (int i = 0; i < bmp.Width; i++)
{
for (int j = 0; j < bmp.Height; j++)
{
bmp.SetPixel(i, j,
Color.FromArgb(
byte.MaxValue - bmp.GetPixel(i, j).R,
byte.MaxValue - bmp.GetPixel(i, j).G,
byte.MaxValue - bmp.GetPixel(i, j).B));
}
}
return (Image)bmp;
}
那是因为 GetPixel
和 SetPixel
方法很慢。不是很慢,但是因为你进行了很多次调用,开销加起来了。
您可以从每个像素只调用一次 GetPixel
而不是三次开始:
public Image InvertColor(Image img) {
Bitmap bmp = new Bitmap(img);
for (int i = 0; i < bmp.Width; i++) {
for (int j = 0; j < bmp.Height; j++) {
Color source = bmp.GetPixel(i, j);
bmp.SetPixel(i, j,
Color.FromArgb(
byte.MaxValue - source.R,
byte.MaxValue - source.G,
byte.MaxValue - source.B
)
);
}
}
return (Image)bmp;
}
这应该使它快两倍。为了更快地获得它,您需要直接访问图像数据。您可以使用 LockBits
method 获取指向图像数据的指针。
这是最快的方法。它使用 ColorMatrix
并且基本上不花时间,即使对于大 Images
.
private Image fastInvert(Image img)
{
float[][] cm = 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}
};
ColorMatrix CM = new ColorMatrix(cm);
ImageAttributes ia = new ImageAttributes();
ia.SetColorMatrix(CM);
using ( Graphics g = Graphics.FromImage(img) )
g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0,
img.Width, img.Height, GraphicsUnit.Pixel, ia);
return img;
}
矩阵数据是 Visual Kicks, who get it right, as opposed to any other site I found, including Bob Powell's 的荣誉,它的更新真的是 hack,甚至对我都不起作用..