C#图片灰度处理(位深度24→位深度8)
- #region 灰度处理
- /// <summary>
- /// 将源图像灰度化,并转化为8位灰度图像。
- /// </summary>
- /// <param name="original"> 源图像。 </param>
- /// <returns> 8位灰度图像。 </returns>
- public static Bitmap RgbToGrayScale(Bitmap original)
- {
- if (original != null)
- {
- // 将源图像内存区域锁定
- Rectangle rect = new Rectangle(, , original.Width, original.Height);
- BitmapData bmpData = original.LockBits(rect, ImageLockMode.ReadOnly,
- PixelFormat.Format24bppRgb);
- // 获取图像参数
- int width = bmpData.Width;
- int height = bmpData.Height;
- int stride = bmpData.Stride; // 扫描线的宽度,比实际图片要大
- int offset = stride - width * ; // 显示宽度与扫描线宽度的间隙
- IntPtr ptr = bmpData.Scan0; // 获取bmpData的内存起始位置的指针
- int scanBytesLength = stride * height; // 用stride宽度,表示这是内存区域的大小
- // 分别设置两个位置指针,指向源数组和目标数组
- int posScan = , posDst = ;
- byte[] rgbValues = new byte[scanBytesLength]; // 为目标数组分配内存
- Marshal.Copy(ptr, rgbValues, , scanBytesLength); // 将图像数据拷贝到rgbValues中
- // 分配灰度数组
- byte[] grayValues = new byte[width * height]; // 不含未用空间。
- // 计算灰度数组
- byte blue, green, red, YUI;
- for (int i = ; i < height; i++)
- {
- for (int j = ; j < width; j++)
- {
- blue = rgbValues[posScan];
- green = rgbValues[posScan + ];
- red = rgbValues[posScan + ];
- YUI = (byte)(0.229 * red + 0.587 * green + 0.144 * blue);
- //grayValues[posDst] = (byte)((blue + green + red) / 3);
- grayValues[posDst] = YUI;
- posScan += ;
- posDst++;
- }
- // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
- posScan += offset;
- }
- // 内存解锁
- Marshal.Copy(rgbValues, , ptr, scanBytesLength);
- original.UnlockBits(bmpData); // 解锁内存区域
- // 构建8位灰度位图
- Bitmap retBitmap = BuiltGrayBitmap(grayValues, width, height);
- return retBitmap;
- }
- else
- {
- return null;
- }
- }
- /// <summary>
- /// 用灰度数组新建一个8位灰度图像。
- /// </summary>
- /// <param name="rawValues"> 灰度数组(length = width * height)。 </param>
- /// <param name="width"> 图像宽度。 </param>
- /// <param name="height"> 图像高度。 </param>
- /// <returns> 新建的8位灰度位图。 </returns>
- private static Bitmap BuiltGrayBitmap(byte[] rawValues, int width, int height)
- {
- // 新建一个8位灰度位图,并锁定内存区域操作
- Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
- BitmapData bmpData = bitmap.LockBits(new Rectangle(, , width, height),
- ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
- // 计算图像参数
- int offset = bmpData.Stride - bmpData.Width; // 计算每行未用空间字节数
- IntPtr ptr = bmpData.Scan0; // 获取首地址
- int scanBytes = bmpData.Stride * bmpData.Height; // 图像字节数 = 扫描字节数 * 高度
- byte[] grayValues = new byte[scanBytes]; // 为图像数据分配内存
- // 为图像数据赋值
- int posSrc = , posScan = ; // rawValues和grayValues的索引
- for (int i = ; i < height; i++)
- {
- for (int j = ; j < width; j++)
- {
- grayValues[posScan++] = rawValues[posSrc++];
- }
- // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
- posScan += offset;
- }
- // 内存解锁
- Marshal.Copy(grayValues, , ptr, scanBytes);
- bitmap.UnlockBits(bmpData); // 解锁内存区域
- // 修改生成位图的索引表,从伪彩修改为灰度
- ColorPalette palette;
- // 获取一个Format8bppIndexed格式图像的Palette对象
- using (Bitmap bmp = new Bitmap(, , PixelFormat.Format8bppIndexed))
- {
- palette = bmp.Palette;
- }
- for (int i = ; i < ; i++)
- {
- palette.Entries[i] = Color.FromArgb(i, i, i);
- }
- // 修改生成位图的索引表
- bitmap.Palette = palette;
- return bitmap;
- }
- #endregion
C#图片二值化处理(位深度8→位深度1)
- #region 二值化
- /*
- 1位深度图像 颜色表数组255个元素 只有用前两个 0对应0 1对应255
- 1位深度图像每个像素占一位
- 8位深度图像每个像素占一个字节 是1位的8倍
- */
- /// <summary>
- /// 将源灰度图像二值化,并转化为1位二值图像。
- /// </summary>
- /// <param name="bmp"> 源灰度图像。 </param>
- /// <returns> 1位二值图像。 </returns>
- public static Bitmap GTo2Bit(Bitmap bmp)
- {
- if (bmp != null)
- {
- // 将源图像内存区域锁定
- Rectangle rect = new Rectangle(, , bmp.Width, bmp.Height);
- BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly,
- PixelFormat.Format8bppIndexed);
- // 获取图像参数
- int leng, offset_1bit = ;
- int width = bmpData.Width;
- int height = bmpData.Height;
- int stride = bmpData.Stride; // 扫描线的宽度,比实际图片要大
- int offset = stride - width; // 显示宽度与扫描线宽度的间隙
- IntPtr ptr = bmpData.Scan0; // 获取bmpData的内存起始位置的指针
- int scanBytesLength = stride * height; // 用stride宽度,表示这是内存区域的大小
- if (width % == )
- {
- leng = width / ;
- }
- else
- {
- leng = width / + ( - (width / % ));
- if (width % != )
- {
- offset_1bit = leng - width / ;
- }
- else
- {
- offset_1bit = leng - width / ;
- }
- }
- // 分别设置两个位置指针,指向源数组和目标数组
- int posScan = , posDst = ;
- byte[] rgbValues = new byte[scanBytesLength]; // 为目标数组分配内存
- Marshal.Copy(ptr, rgbValues, , scanBytesLength); // 将图像数据拷贝到rgbValues中
- // 分配二值数组
- byte[] grayValues = new byte[leng * height]; // 不含未用空间。
- // 计算二值数组
- int x, v, t = ;
- for (int i = ; i < height; i++)
- {
- for (x = ; x < width; x++)
- {
- v = rgbValues[posScan];
- t = (t << ) | (v > ? : );
- if (x % == )
- {
- grayValues[posDst] = (byte)t;
- posDst++;
- t = ;
- }
- posScan++;
- }
- if ((x %= ) != )
- {
- t <<= - x;
- grayValues[posDst] = (byte)t;
- }
- // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
- posScan += offset;
- posDst += offset_1bit;
- }
- // 内存解锁
- Marshal.Copy(rgbValues, , ptr, scanBytesLength);
- bmp.UnlockBits(bmpData); // 解锁内存区域
- // 构建1位二值位图
- Bitmap retBitmap = twoBit(grayValues, width, height);
- return retBitmap;
- }
- else
- {
- return null;
- }
- }
- /// <summary>
- /// 用二值数组新建一个1位二值图像。
- /// </summary>
- /// <param name="rawValues"> 二值数组(length = width * height)。 </param>
- /// <param name="width"> 图像宽度。 </param>
- /// <param name="height"> 图像高度。 </param>
- /// <returns> 新建的1位二值位图。 </returns>
- private static Bitmap twoBit(byte[] rawValues, int width, int height)
- {
- // 新建一个1位二值位图,并锁定内存区域操作
- Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format1bppIndexed);
- BitmapData bmpData = bitmap.LockBits(new Rectangle(, , width, height),
- ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);
- // 计算图像参数
- int offset = bmpData.Stride - bmpData.Width / ; // 计算每行未用空间字节数
- IntPtr ptr = bmpData.Scan0; // 获取首地址
- int scanBytes = bmpData.Stride * bmpData.Height; // 图像字节数 = 扫描字节数 * 高度
- byte[] grayValues = new byte[scanBytes]; // 为图像数据分配内存
- // 为图像数据赋值
- int posScan = ; // rawValues和grayValues的索引
- for (int i = ; i < height; i++)
- {
- for (int j = ; j < bmpData.Width / ; j++)
- {
- grayValues[posScan] = rawValues[posScan];
- posScan++;
- }
- // 跳过图像数据每行未用空间的字节,length = stride - width * bytePerPixel
- posScan += offset;
- }
- // 内存解锁
- Marshal.Copy(grayValues, , ptr, scanBytes);
- bitmap.UnlockBits(bmpData); // 解锁内存区域
- // 修改生成位图的索引表
- ColorPalette palette;
- // 获取一个Format8bppIndexed格式图像的Palette对象
- using (Bitmap bmp = new Bitmap(, , PixelFormat.Format1bppIndexed))
- {
- palette = bmp.Palette;
- }
- for (int i = ; i < ; i = +)
- {
- palette.Entries[i] = Color.FromArgb(i, i, i);
- }
- // 修改生成位图的索引表
- bitmap.Palette = palette;
- return bitmap;
- }
- #endregion
C#图片灰度处理(位深度24→位深度8)的更多相关文章
- C#图片灰度处理(位深度24→位深度8),用灰度数组byte[]新建一个8位灰度图像Bitmap 。
原文:C#图片灰度处理(位深度24→位深度8) #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> ...
- C#图片灰度处理(位深度24→位深度8)、C#图片二值化处理(位深度8→位深度1)
C#图片灰度处理(位深度24→位深度8) #region 灰度处理 /// <summary> /// 将源图像灰度化,并转化为8位灰度图像. /// </summary> / ...
- 图像转置的SSE优化(支持8位、24位、32位),提速4-6倍。
一.前言 转置操作在很多算法上都有着广泛的应用,在数学上矩阵转置更有着特殊的意义.而在图像处理上,如果说图像数据本身的转置,除了显示外,本身并无特殊含义,但是在某些情况下,确能有效的提高算法效率,比如 ...
- SSE图像算法优化系列四:图像转置的SSE优化(支持8位、24位、32位),提速4-6倍
一.前言 转置操作在很多算法上都有着广泛的应用,在数学上矩阵转置更有着特殊的意义.而在图像处理上,如果说图像数据本身的转置,除了显示外,本身并无特殊含义,但是在某些情况下,确能有效的提高算法效率,比如 ...
- MD5值转换(Hex 32位 <-> base64 24位)
关于MD5值的原理本文不在介绍,本文主要介绍MD5值的两种编码的相互转换(32位和BASE64编码的24位),实际应用过程中经常会涉及到两种编码的相互转换.快熟使用工具tomeko.net. C#示例 ...
- C#保存图片到文件夹区分8位和24位
1.保存图像--24位位图(显示的图像,包括增加结果到界面上的数据) Image image2 = default(Image); image2 = cogRecordDisplay1.CreateC ...
- 怎么把PNG图的位深度24位变成32位
在PS里把图片的变成层模式,不透明度设置成99%,在保存成PNG
- 颜色模式中8位,16位,24位,32位色彩是什么意思?会有什么区别?计算机颜色格式( 8位 16位 24位 32位色)<转>
颜色模式中8位,16位,24位,32位色彩是什么意思?会有什么区别简单地说这里说的位数和windows系统显示器设置中的颜色位数是一样的.表示的是能够显示出来的颜色的多少. 8位的意思是说,能够显示出 ...
- C# AES的128位、192位、256位加密
C# AES的128位.192位.256位加密 AES加密原理,这里就不解释了,自行百度.这里主要细说AES的CBC加密模式下的128位.192位.256位加密区别,参考 对称加密和分组加密中的四 ...
随机推荐
- [WebGL入门]十三,minMatrix.js和坐标变换矩阵
注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,假设翻译有误,欢迎大家指 ...
- html常用属性border-radius、linear-gradient怎么使用
html常用属性border-radius.linear-gradient怎么使用 一.总结 一句话总结: 1.border-radius: 8px 8px 8px 8px !important; 2 ...
- 【hdu2222】【poj2945】AC自动机入门题
HDU2222 传送门 题目分析 裸题:注意构建自动机用的是模式串,思想和kmp很类似. code: #include<iostream> #include<cstdio> # ...
- lucene 7.x 查询
@Test public void indexSearch() throws IOException, ParseException { //Termquery:精确string查询 // Query ...
- Facebook巴特尔与谷歌移动广告 急于打开中国市场
随着Facebook(62.5, -0.69, -1.09%)即将设立了销售办事处在北京发酵消息.谷歌(556.33, 2.43, 0.44%)似还差点自觉保护国内市场. 6月5日,谷歌在深圳举行了面 ...
- QT开发环境的建立以及QTE4.6.3、tslib1.4的移植过程
1.首先是建立Linux开发环境1.1.在windowsXP下安装博创公司提供的虚拟机软件VMware Workstation,版本为VMware-workstation-full-7.0.1-227 ...
- Cocos2d-x3.1下实现相似iOS页面滑动指示圆点
原文地址:http://blog.csdn.net/qqmcy/article/details/37612457 代码下载:http://download.csdn.net/detail/qqmcy/ ...
- Why I Choose Delphi Summary
Over the summer, there has been a number of blog posts on this topic, but I haven't seen a complete ...
- Boltzmann 玻尔兹曼机(BM)
Hopfield + 模拟退火 ⇒ Boltimann machine(随机神经网络),由 Hinton 和他的长期合作者 Sejnowski(Hopfield 的博士生) 共同提出. 1. 基本公式 ...
- 关于MySql链接url参数的设置 专题
报错: Establishing SSL connection without server's identity verification is not recommended. According ...