C#对图像像素处理的三种方式

简介:

在C#中,可以采用直接获取像素法(GetPixel)、内存拷贝法和指针法(unsafe)来获取图像像素并进行处理。

下面以图像的灰度化为例说明具体的处理方法和速度的比较(1G内存,P4处理器测试)。

1.GetPixel方法

GetPixel(i,j)和SetPixel(i, j,Color)可以直接得到图像的一个像素的Color结构,但是处理速度比较慢,处理一副180*180的图像大约需要100.48ms。

private void pixel_Click(object sender, EventArgs e)
{
    if(curBitmap != null)
    {
        myTimer.ClearTimer();
        myTimer.Start();
        Color curColor;
        int ret;
        for (int i = 0; i < curBitmap.Width; i++)
        {
            for (int j = 0; j < curBitmap.Height ; j++)
            {
                curColor = curBitmap.GetPixel(i,j);
                ret = (int)(curColor.R * 0.299 + curColor.G * 0.587 + curColor.B * 0.114);
                curBitmap.SetPixel(i, j, Color.FromArgb(ret, ret, ret));
            }
        }
        myTimer.Stop();
        timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒"; 
        Invalidate();
    }
}

2.内存拷贝法

内存拷贝法就是采用System.Runtime.InteropServices.Marshal.Copy将图像数据拷贝到数组中,然后进行处理,这不需要直接对指针进行操作,不需采用unsafe,处理速度和指针处理相差不大,
处理一副180*180的图像大约需要1.32ms。
private void memory_Click(object sender, EventArgs e)
{
    if (curBitmap != null)
    {
        myTimer.ClearTimer();
        myTimer.Start();
        Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
        System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
        IntPtr ptr = bmpData.Scan0;
        int bytes = curBitmap.Width * curBitmap.Height * 3;
        byte[] rgbValues = new byte[bytes];
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
        double colorTemp = 0;
        for (int i = 0; i < rgbValues.Length; 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;
        }
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes);
        curBitmap.UnlockBits(bmpData);
        myTimer.Stop();
        timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒"; 
        Invalidate();
    }
}

3.指针法

指针在c#中属于unsafe操作,需要用unsafe括起来进行处理,速度最快,处理一副180*180的图像大约需要1.16ms。
采用byte* ptr = (byte*)(bmpData.Scan0); 获取图像数据根位置的指针,然后用bmpData.Scan0获取图像的扫描宽度,就可以进行指针操作了。
 
private void pointer_Click(object sender, EventArgs e)
{
    if (curBitmap != null)
    {
        myTimer.ClearTimer();
        myTimer.Start();
        Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
        System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.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;
            }
        }
        curBitmap.UnlockBits(bmpData);
        myTimer.Stop();
        timeBox.Text = myTimer.Duration.ToString("####.##") + " 毫秒"; 
        Invalidate();
    }

}

本文转自feisky博客园博客,原文链接:http://www.cnblogs.com/feisky/archive/2009/11/02/1594840.html,如需转载请自行联系原作者



相关文章
|
4月前
|
监控 API 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK获取每张图像的微秒时间和FrameID功能(C#)
79 0
|
4月前
|
存储 传感器 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK修改图像像素格式Mono8或者Mono10(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK修改图像像素格式Mono8或者Mono10(C#)
117 0
|
4月前
|
存储 数据处理 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机的高速图像保存(C#)
62 0
|
4月前
|
监控 算法 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现获取图像并对图像进行边缘检测(C#)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现获取图像并对图像进行边缘检测(C#)
62 1
|
4月前
|
存储 监控 开发工具
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为AVI视频格式(C#)
Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为AVI视频格式(C#)
55 0
|
4月前
|
数据采集 API 开发工具
Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存(C#)
Baumer工业相机堡盟工业相机如何通过BGAPI SDK实现Raw格式的图像保存(C#)
60 0
|
4月前
|
存储 传感器 监控
Baumer工业相机堡盟工业相机如何通过BGAPISDK将相机图像高速保存到电脑内存(C#)
Baumer工业相机堡盟工业相机如何通过BGAPISDK将相机图像高速保存到电脑内存(C#)
84 0
|
9天前
|
数据采集 JavaScript C#
C#图像爬虫实战:从Walmart网站下载图片
C#图像爬虫实战:从Walmart网站下载图片
|
4月前
|
存储 数据处理 开发工具
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机图像转换由Mono10转换为Mono8(C#)
Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机图像转换由Mono10转换为Mono8(C#)
68 0
|
3月前
|
并行计算 算法 C#
C# Mandelbrot和Julia分形图像生成程序更新到2010-9-14版 支持多线程计算 多核处理器
此文档是一个关于分形图像生成器的介绍,作者分享了个人开发的M-J算法集成及色彩创新,包括源代码和历史版本。作者欢迎有兴趣的读者留言交流,并提供了邮箱(delacroix_xu@sina.com)以分享资源。文中还展示了程序的发展历程,如增加了真彩色效果、圈选放大、历史记录等功能,并分享了几幅精美的分形图像。此外,还提到了程序的新特性,如导入ini文件批量输出图像和更新一批图片的功能。文档末尾附有多张程序生成的高分辨率分形图像示例。