分享

GDI 入门(C#高速处理版本)

 Cloud书屋 2012-11-20

首先感谢CSDN的朋友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+,写得比较简单,让高手见笑了。欢迎高手给我指点

邮箱:bobui@163.com

QQ:125941562

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多