首先感谢优快云的朋友laviewpbt为我给我的建议。
laviewpbt提出使用getpixel处理速度太慢,上不了档次。
这里我再给大家写两种处理速度更快的图形处理方式。
下面是个内存操作灰度的程序:
bmp = new Bitmap(Application.StartupPath + "//1.jpg");
Bitmap bmp2 = (Bitmap)bmp.Clone();
int width = bmp2.Width;
int height = bmp2.Height;
Rectangle rect = new Rectangle(0, 0, width, height);
//用可读写的方式锁定全部位图像素
BitmapData bmpData = bmp2.LockBits(rect, ImageLockMode.ReadWrite, bmp2.PixelFormat);
//得到首地址
IntPtr ptr = bmpData.Scan0;
//24位bmp位图字节数
int bytes = width * height * 3;
byte[] rgbValues = new byte[bytes];
Marshal.Copy(ptr, rgbValues, 0, bytes);
//灰度化
double colorTemp = 0;
for (int i = 0; i < bytes; i += 3)
{
colorTemp = rgbValues[i + 2] * 0.299 + rgbValues[i + 1] * 0.587 + rgbValues[i] * 0.114;
rgbValues[i] = rgbValues[i+1] = rgbValues[i+2] = (byte)colorTemp;
}
//还原位图
Marshal.Copy(rgbValues, 0, ptr, bytes);
bmp2.UnlockBits(bmpData);
Graphics g = this.CreateGraphics();
g.DrawImage(bmp2, new Rectangle(410, 0, 200, 200));
g.Dispose();
bmp2.Dispose();
够仔细的朋友很容易看出,其实我们只是把图像的像素点放到内存中处理了。我们知道在内存中处理肯定是最快的了。
下面再写一个用指针的
bmp = new Bitmap(Application.StartupPath + "//1.jpg");
Bitmap bmp2 = (Bitmap)bmp.Clone();
int width = bmp2.Width;
int height = bmp2.Height;
Rectangle rect = new Rectangle(0, 0, width, height);
//用可读写的方式锁定全部位图像素
BitmapData bmpData = bmp2.LockBits(rect, ImageLockMode.ReadWrite, bmp2.PixelFormat);
byte temp = 0;
//启用不安全模式
unsafe
{
//获取首地址
byte* ptr = (byte*)(bmpData.Scan0);
//二维图像循环
for (int i = 0; i < bmpData.Height; i++)
{
for (int j = 0; j < bmpData.Width; j++)
{
temp = (byte)(0.299 * ptr[2] + 0.587 * ptr[1] + 0.114 * ptr[0]);
ptr[0] = ptr[1] = ptr[2] = temp;
ptr += 3;
}
//指针移向下一行数组的首个字节
ptr += bmpData.Stride - bmpData.Width * 3;
}
bmp2.UnlockBits(bmpData);
}
Graphics g = this.CreateGraphics();
g.DrawImage(bmp2, new Rectangle(615, 0, 200, 200));
g.Dispose();
bmp2.Dispose();
C#默认不能使用指针操作,所以我们使用了unsafe(不安全模式),注意:使用不安全模式调试时需要配置VS,在项目的属性内设置启用不安全模式调试
本人也在学习GDI+,写得比较简单,让高手见笑了。欢迎高手给我指点
QQ:125941562
814

被折叠的 条评论
为什么被折叠?



