广告
返回顶部
首页 > 资讯 > 精选 >C#的Bitmap图像处理方法有哪些
  • 219
分享到

C#的Bitmap图像处理方法有哪些

2023-06-25 15:06:39 219人浏览 独家记忆
摘要

本篇内容介绍了“C#的Bitmap图像处理方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Bitmap类Bitmap对象封装了GDI

本篇内容介绍了“C#的Bitmap图像处理方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

Bitmap类

Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要方法和属性如下:

GetPixel方法和SetPixel方法:获取和设置一个图像的指定像素的颜色.
2. PixelFORMat属性:返回图像的像素格式.
3. Palette属性:获取和设置图像所使用的颜色调色板.
4. Height Width属性:返回图像的高度和宽度.
5. LockBits方法和UnlockBits方法:分别定和解锁系统内存中的位图像素.在基于像素点的图像处理方法中使用LockBits和UnlockBits是一个很好的方式,这两种方法可以使我们指定像素的范围来控制位图的任意一部分,从而消除了通过循环对位图的像素逐个进行处理,每调用LockBits之后都应该调用一次UnlockBits.

BitmapData类

BitmapData对象指定了位图的属性
1. Height属性:被锁定位图的高度.
2. Width属性:被锁定位图的宽度.
3. PixelFormat属性:数据的实际像素格式.
4. Scan0属性:被锁定数组的首字节地址,如果整个图像被锁定,则是图像的第一个字节地址.
5. Stride属性:步幅,也称为扫描宽度.

这里要重点说说Stride属性,这个和Width有什么区别呢,可以这么说,如果你的图片大小也就是图片字节是4的整数倍,那么Stride与Width是相等的,否则Stride就是大于Width的最小4的整数倍。在处理过程中,Stride肯定是4的整数倍,这里是个坑啊。。。

例1:有一个一维像素点阵数组,里面放的是每个像素点的灰度值,知道宽和高,要转换成bitmap

/// <summary>/// 像素点阵转换为bitmap/// </summary>/// <param name="rawValues">byte[]数组</param>/// <param name="width">图片的宽度</param>/// <param name="height">图片的高度</param>/// <returns>bitmap图片</returns>public static Bitmap ToGrayBitmap(byte[] rawValues, int width, int height){    Bitmap bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);    BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);     获取图像参数      //bmpData.Stride = width;    int stride = bmpData.Stride;  // 扫描线的宽度      int offset = stride - width;  // 显示宽度与扫描线宽度的间隙      IntPtr iptr = bmpData.Scan0;  // 获取bmpData的内存起始位置      int scanBytes = stride * height;// 用stride宽度,表示这是内存区域的大小       下面把原始的显示大小字节数组转换为内存中实际存放的字节数组      int posScan = 0, posReal = 0;// 分别设置两个位置指针,指向源数组和目标数组      byte[] pixelValues = new byte[scanBytes];  //为目标数组分配内存      for (int x = 0; x < height; x++)    {         下面的循环节是模拟行扫描          for (int y = 0; y < width; y++)        {            pixelValues[posScan++] = rawValues[posReal++];        }        posScan += offset;  //行扫描结束,要将目标位置指针移过那段“间隙”      }     用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中      System.Runtime.InteropServices.Marshal.Copy(pixelValues, 0, iptr, scanBytes);    bmp.UnlockBits(bmpData);  // 解锁内存区域       下面的代码是为了修改生成位图的索引表,从伪彩修改为灰度      ColorPalette tempPalette;    using (Bitmap tempBmp = new Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format8bppIndexed))    {        tempPalette = tempBmp.Palette;    }    for (int i = 0; i < 256; i++)    {        tempPalette.Entries[i] = System.Drawing.Color.FromArgb(i, i, i);    }     bmp.Palette = tempPalette;      算法到此结束,返回结果      return bmp;}

至于24位位图数据其实就是 一个像素点有rgb三个值而已,道理一样。

例2::根据图片得到他的灰度数组

//8位位图得到除去文件头信息的一位灰度数组  BitmapData bmpData = map.LockBits(new System.Drawing.Rectangle(0, 0, map.Width, map.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);  获取图像参数   int stride = bmpData.Stride;  // 扫描线的宽度   int offset = stride - map.Width;  // 显示宽度与扫描线宽度的间隙   IntPtr iptr = bmpData.Scan0;  // 获取bmpData的内存起始位置   int scanBytes = stride * map.Height;// 用stride宽度,表示这是内存区域的大小    下面把原始的显示大小字节数组转换为内存中实际存放的字节数组   mapdata = new byte[scanBytes];  //为目标数组分配内存 System.Runtime.InteropServices.Marshal.Copy(iptr, mapdata, 0, scanBytes); //copy内存中数据到数组中

这里对与bitmapdata的操作方式是ReadOnly

下面的三个例子分别基于像素(GetPixel和SetPixel)、基于内存、基于指针这三种方法增强图片对比度。均测试通过

运行时间:

1)基于像素:400-600ms
2)基于内存:17-18ms
3)基于指针:20-23ms
利用LUT,应该可以进一步减少运行时间

 // 第一种方法:像素提取法。速度慢        public Bitmap MethodBaseOnPixel(Bitmap bitmap,int degree)        {            Color curColor;            int grayR, grayG, grayB;             double Deg = (100.0 + degree) / 100.0;            for (int i = 0; i < bitmap.Width; i++)            {                for (int j = 0; j < bitmap.Height; j++)                {                    curColor = bitmap.GetPixel(i, j);                    grayR =Convert.ToInt32((((curColor.R / 255.0 - 0.5) * Deg + 0.5)) * 255);                    grayG = Convert.ToInt32((((curColor.G / 255.0 - 0.5) * Deg + 0.5)) * 255);                    grayB = Convert.ToInt32((((curColor.B / 255.0 - 0.5) * Deg + 0.5)) * 255);                    if (grayR < 0)                        grayR = 0;                    else if (grayR > 255)                        grayR = 255;                     if (grayB < 0)                        grayB = 0;                    else if (grayB > 255)                        grayB = 255;                     if (grayG < 0)                        grayG = 0;                    else if (grayG > 255)                        grayG = 255;                      bitmap.SetPixel(i, j, Color.FromArgb(grayR, grayG, grayB));                }            }             return bitmap;        }
// 第二种方法:基于内存        public unsafe Bitmap MethodBaseOnMemory(Bitmap bitmap, int degree)        {            if (bitmap == null)            {                return null;            }            double Deg = (100.0 + degree) / 100.0;             int width = bitmap.Width;            int height = bitmap.Height;             int length = height * 3 * width;            byte[] RGB = new byte[length];             BitmapData data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);             System.IntPtr Scan0 = data.Scan0;            System.Runtime.InteropServices.Marshal.Copy(Scan0, RGB, 0, length);             double gray = 0;            for (int i = 0; i < RGB.Length; i += 3)            {                for (int j = 0; j < 3; j++)                {                    gray = (((RGB[i + j] / 255.0 -0.5) * Deg+0.5)) * 255.0;                    if (gray > 255)                        gray = 255;                     if (gray < 0)                        gray = 0;                    RGB[i + j] = (byte) gray;                }            }             System.Runtime.InteropServices.Marshal.Copy(RGB, 0, Scan0, length);// 此处Copy是之前Copy的逆操作            bitmap.UnlockBits(data);            return bitmap;        }    }
//第三种方法:基于指针        public unsafe Bitmap MethodBaseOnPtr(Bitmap b, int degree)        {            if (b == null)            {                return null;            }            try            {                double num = 0.0;                double num2 = (100.0 + degree) / 100.0;                num2 *= num2;                int width = b.Width;                int height = b.Height;                BitmapData bitmapdata = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);                byte* numPtr = (byte*)bitmapdata.Scan0;                 int offset = bitmapdata.Stride - (width * 3);                for (int i = 0; i < height; i++)                {                    for (int j = 0; j < width; j++)                    {                        for (int k = 0; k < 3; k++)                        {                            num = ((((((double)numPtr[k]) / 255.0) - 0.5) * num2) + 0.5) * 255.0;                            if (num < 0.0)                            {                                num = 0.0;                            }                            if (num > 255.0)                            {                                num = 255.0;                            }                            numPtr[k] = (byte)num;                        }                        numPtr += 3;                     }                    numPtr += offset;                }                b.UnlockBits(bitmapdata);                return b;            }            catch            {                return b;            }        }

“C#的Bitmap图像处理方法有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: C#的Bitmap图像处理方法有哪些

本文链接: https://www.lsjlt.com/news/305867.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C#的Bitmap图像处理方法有哪些
    本篇内容介绍了“C#的Bitmap图像处理方法有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Bitmap类Bitmap对象封装了GDI...
    99+
    2023-06-25
  • C# Bitmap图像处理加速的实现
    目录BitmapData类传统代码使用BitmapData的代码效率对比代码GPU加速生成Dll调用Dll耗时BitmapData类 BitmapData类专门用于位图处理,与Bit...
    99+
    2022-11-12
  • C# Bitmap图像处理(含增强对比度的三种方法)
    目录Bitmap类BitmapData类参考:Bitmap类 Bitmap对象封装了GDI+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据...
    99+
    2022-11-12
  • JavaScript中有哪些图像处理的方法
    本篇文章给大家分享的是有关JavaScript中有哪些图像处理的方法,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。JavaScript图像读取...
    99+
    2022-10-19
  • CSS处理图像上文字的方法有哪些
    这篇文章给大家分享的是有关CSS处理图像上文字的方法有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。什么是csscss是一种用来表现HTML或XML等文件样式的计算机语言,主要是用来设计网页的样式,使网页更加...
    99+
    2023-06-14
  • c++异常处理的方法有哪些
    在C++中,有以下几种异常处理的方法:1. try-catch语句块:使用try-catch语句块可以捕获和处理异常。在try块中编...
    99+
    2023-10-10
    c++
  • JavaScript中有哪些图像处理库
    这篇文章将为大家详细讲解有关JavaScript中有哪些图像处理库,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。javascript是一种什么语言javascript是一种动态类型、弱类型的...
    99+
    2023-06-14
  • Python有哪些图像处理工具
    本篇内容介绍了“Python有哪些图像处理工具”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1. scikit Imagescikit-im...
    99+
    2023-06-16
  • Python传统图像处理皮肤区域检测的方法有哪些
    这篇文章主要介绍“Python传统图像处理皮肤区域检测的方法有哪些”,在日常操作中,相信很多人在Python传统图像处理皮肤区域检测的方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python传统图...
    99+
    2023-06-21
  • 常用的图像处理软件有哪些
    常用的图像处理软件有:1、照片修图,一款手机的专属修图小工具;2、ps修图软件,特别专业的一款手机应用软件;3、天天P图,特别有趣的一款修图手机应用app;4、照片编辑P图,专门为修图推出的一款功能非常强大的软件;5、P图照片编辑器等等。常...
    99+
    2023-07-10
  • 发JavaScript中有哪些图像处理库
    发JavaScript中有哪些图像处理库,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。1. Picapica 可在浏览器上实现高质量而且高...
    99+
    2022-10-19
  • 常用的Matlab图像处理函数有哪些
    常用的Matlab图像处理函数有以下几个: imread:用于读取图像文件并将其存储为矩阵形式的图像。 imshow:用于显示图像...
    99+
    2023-10-24
    Matlab
  • C#绘图基本方法有哪些
    今天小编给大家分享一下C#绘图基本方法有哪些的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、得到Graphics对象1.O...
    99+
    2023-07-04
  • python图像处理基本操作有哪些
    这篇文章主要介绍python图像处理基本操作有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、PIL库对图像的基本操作1、读取图片PIL网上有很多介绍,这里不再讲解。直接操作,读取一张图片,将其转换为灰度图像,...
    99+
    2023-06-15
  • c语言字符串处理的方法有哪些
    C语言字符串处理的方法有以下几种:1. 使用字符数组:可以通过定义一个字符数组来存储字符串,然后使用相关的字符串处理函数来对字符串进...
    99+
    2023-08-30
    c语言
  • c语言处理字符串的方法有哪些
    C语言处理字符串的方法有以下几种:1. 字符串赋值:使用strcpy函数将一个字符串赋值给另一个字符串。2. 字符串连接:使用str...
    99+
    2023-08-24
    c语言
  • Java图像处理框架Marvin的功能有哪些
    这篇文章将为大家详细讲解有关Java图像处理框架Marvin的功能有哪些,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Marvin 1.4.0 发布了,该版本包含新的插件接口,允许开发者插入...
    99+
    2023-06-17
  • python图像平滑处理的方法
    这篇文章主要介绍“python图像平滑处理的方法”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“python图像平滑处理的方法”文章能帮助大家解决问题。前言:图像滤波是图像处理和计算机视觉中最常用、最...
    99+
    2023-07-02
  • OpenCV通过Mat遍历图像的方法有哪些
    本文小编为大家详细介绍“OpenCV通过Mat遍历图像的方法有哪些”,内容详细,步骤清晰,细节处理妥当,希望这篇“OpenCV通过Mat遍历图像的方法有哪些”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。我们在实际...
    99+
    2023-06-29
  • C#处理异常的方式有哪些
    本篇内容主要讲解“C#处理异常的方式有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C#处理异常的方式有哪些”吧!关于异常,从我们一开始写代码的时候就开始伴随着我们,只不过那时还没入门,脑子...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作