热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#中如何高性能地把图像转换成grayscale的

C#里把图片灰度化:先是用以下代码,能转换,但经测试性能比较低,在窗口中预览灰度化的采集视频,相当卡顿,这是因为在两重循环里大量调用GetPixel和SetPixelpriva

C#里把图片灰度化: 先是用以下代码, 能转换, 但经测试性能比较低, 在窗口中预览灰度化的采集视频, 相当卡顿, 这是因为在两重循环里大量调用GetPixel和SetPixel

private Bitmap rgb2gray(Bitmap bm)
{
//Row-wise iteration through the Bitmap
for (int y = 0; y {
for (int x = 0; x {
Color pixelColor = bm.GetPixel(x, y);
int pixelLuminance = (int)(pixelColor.R * 0.2126 + pixelColor.G * 0.7152 + pixelColor.B * 0.0722);
bm.SetPixel(x, y, Color.FromArgb(pixelLuminance, pixelLuminance, pixelLuminance));
}//for
}//for
return bm;
}//rgb2gray(Bitmap)

?

经搜索, 在http://stackoverflow.com/questions/1580130/high-speed-performance-of-image-filtering-in-c-sharp 里找到以下代码:?

public static void GrayScaleImage(Bitmap image)
{
if (image == null)
throw new ArgumentNullException("image");
// lock the bitmap.
var data = image.LockBits(
new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, image.PixelFormat);
try
{
unsafe
{
// get a pointer to the data.
byte* ptr = (byte*)data.Scan0;
// loop over all the data.
for (int i = 0; i {
for (int j = 0; j {
// calculate the gray value.
byte y = (byte)(
(0.299 * ptr[2]) +
(0.587 * ptr[1]) +
(0.114 * ptr[0]));
// set the gray value.
ptr[0] = ptr[1] = ptr[2] = y;
// increment the pointer.
ptr += 3;
}
// move on to the next line.
ptr += data.Stride - data.Width * 3;
}
}
}
finally
{
// unlock the bits when done or when
// an exception has been thrown.
image.UnlockBits(data);
}
}

?

?改用以上代码, 经测试, 性能可以, 但是处理后的图片有些问题, 左边的大部分灰度化的区域有栅格, 右边有一小段区域没有灰度化. ?这当然难不倒老杨, ?老杨感觉是ptr指向的索引不正确的问题, ?参考了下其他代码(https://github.com/baobaohuang/Graphic_gray/blob/cd1d9b543762c23a8fc232e21f8de15dd810e8b2/gray/Program.cs ?, 这个也可以工作, 性能高于最初的代码,但低于上面的代码), ?修正代码如下:?

public static void GrayScaleImage(Bitmap image)
{
if (image == null)
throw new ArgumentNullException("image");
// lock the bitmap.
var data = image.LockBits(
new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
try
{
unsafe
{
// get a pointer to the data.
byte* ptr = (byte*)data.Scan0;
// loop over all the data.
for (int i = 0; i {
ptr = (byte*)data.Scan0 + i*data.Stride;
for (int j = 0; j {
// calculate the gray value.
byte y = (byte)(
(0.299 * ptr[2]) +
(0.587 * ptr[1]) +
(0.114 * ptr[0]));
// set the gray value.
ptr[0] = ptr[1] = ptr[2] = y;
// increment the pointer.
ptr += 3;
}
}
}
}
finally
{
// unlock the bits when done or when
// an exception has been thrown.
image.UnlockBits(data);
}
}

?

最后测试, 以上代码效果perfect ! ?不过后来发现, 其实两段代码的处理ptr的方式都一样可以, 主要是

var data = image.LockBits(
new Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);

?这里必须用PixelFormat.Format24bppRgb


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
author-avatar
勇淑丁
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有