C# 图像处理:将图像(24位真彩)转为 8位灰度图像 采用了内存法,大大提高了效率
/// <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; for (int i = ; i < height; i++)
{
for (int j = ; j < width; j++)
{ blue = rgbValues[posScan];
green = rgbValues[posScan + ];
red = rgbValues[posScan + ];
grayValues[posDst] = (byte)((blue + green+red)/);
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;
}
C# 图像处理:将图像(24位真彩)转为 8位灰度图像 采用了内存法,大大提高了效率的更多相关文章
- 微信公众平台接口获取时间戳为10位,java开发需转为13位
问题1:为什么会生成13位的时间戳,13位的时间戳和10时间戳分别是怎么来的 ? java的date默认精度是毫秒,也就是说生成的时间戳就是13位的,而像c++或者php生成的时间戳默认就是10位的, ...
- MATLAB读取黑白图像显示却是黑色,24位深转8位深黑白图像解决方法
1.24位深转8位深: ps将24位深原图.png保存为GIF图256即为8位,再将8位gif图转为需要的.png,即转为8位深png图. 2.MATLAB读取黑白图像显示几乎全为黑色: 这是最近处理 ...
- C#关于时间(获取特定格式的时间及多种方式获取当前时间戳)以及10位和13位时间戳转为特定格式
C#关于时间(获取特定格式的时间及多种方式获取当前时间戳)以及10位和13位时间戳转为特定格式 置顶 2018年03月06日 19:16:51 黎筱曦 阅读数:19098 标签: C#时间 更多 个人 ...
- 10位时间戳转为C#格式时间
/// <summary> /// 10位时间戳转为C#格式时间 /// </summary> /// <param name=”timeStamp”></p ...
- 【python图像处理】图像的缩放、旋转与翻转
[python图像处理]图像的缩放.旋转与翻转 图像的几何变换,如缩放.旋转和翻转等,在图像处理中扮演着重要的角色,python中的Image类分别提供了这些操作的接口函数,下面进行逐一介绍. 1.图 ...
- Win8 Metro(C#) 数字图像处理--1 图像打开,保存
原文:Win8 Metro(C#) 数字图像处理--1 图像打开,保存 作为本专栏的第一篇,必不可少的需要介绍一下图像的打开与保存,一便大家后面DEMO的制作. Win8Metro编程中,图像相关 ...
- < python PIL - 批量图像处理 - RGB图像生成灰度图像 >
< python PIL - 批量图像处理 - RGB图像生成灰度图像 > 直接用python自带的PIL图像库,将一个文件夹下所有jpg/png的RGB图像转换成灰度/黑白图像 from ...
- Python图像处理丨图像腐蚀与图像膨胀
摘要:本篇文章主要讲解Python调用OpenCV实现图像腐蚀和图像膨胀的算法. 本文分享自华为云社区<[Python图像处理] 八.图像腐蚀与图像膨胀>,作者: eastmount . ...
- C# 内存法图像处理
内存法通过把图像储存在内存中进行处理,效率大大高于GetPixel方法,安全性高于指针法. 笔者当初写图像处理的时候发现网上多是用GetPixel方法实现,提到内存法的时候也没有具体实现,所以笔者在这 ...
随机推荐
- vs code编辑器格式化react jsx插件
vs code格式化jsx比较适合的插件是react-beautify: 格式化中遇到的问题是indent几格,这个问题的解决是你在space里设置几格这个插件就会自动格式化出几格.
- CSS的4种定位方式比较
CSS有四种定位(Positioning)方法:Static,Relative, Absolute和Fixed 元素flow, overlap 相对参照物: 能否用offset( top, left, ...
- 用ng-style修改元素的color, size等
1) 在Controller中定义变量myStyle var myStyle={'background-color':'blue'} $scope.myStyle = myStyle; 2) 在HTM ...
- 获取图片src
用jquery获取图片src(不知道为什么总是undefined): $('img').eq(i).src; $('img').eq(i).attr('src'); //上面两种都是获取不到,不知道为 ...
- Redis数据结构深入解析
- 零基础学习python_文件(28-30课)
本人小白一枚,随着现在对测试要求越来越高,动不动就要去会一门编程语言,没办法只能学习学习Python,今天看到几个月前还是菜鸟的人突然就已经能使用Python写简单系统了,没办法,虽然之前也简单学习过 ...
- js_字符转Unicode
在开发中总会遇到关于Unicode的转码和解码,每次都找工具转/解码很麻烦 ,今天在网上get到一个简单的转/解Unicode的函数. var UnicodeFun = { toUnicode: fu ...
- swing 下拉菜单
package rom; import java.lang.*; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; i ...
- 部署django项目,sqlite3数据库出错sqlite3.NotSupportedError: URIs not supported
如果遇到这个错误 sqlite3.NotSupportedError: URIs not supported 修改类似 该路径 的 base.py文件 /root/.virtualenvs/fkPy3 ...
- jquery小效果:新浪游戏右侧导航菜单 (页面效果)
偷盗:新浪游戏右侧导航菜单 http://games.sina.com.cn 效果: 随着页面的滚动,左侧页面的内容,和右侧的导航菜单的按钮文字对应: 点击右侧的导航按钮,左侧页面滚动到相应的内容 2 ...