C# 内存法图像处理

内存法通过把图像储存在内存中进行处理,效率大大高于GetPixel方法,安全性高于指针法。

笔者当初写图像处理的时候发现网上多是用GetPixel方法实现,提到内存法的时候也没有具体实现,所以笔者在这里具体实现一下- -,望指正。

首先讲一下用到的一些方法。

1.LockBits和UnlockBits:使用 LockBits 方法,可在系统内存中锁定现有的位图,以便通过编程方式进行更改,每调用LockBits之后都应该调用一次UnlockBits。

2.Scan0:图像的第一个字节地址。

3.Stride:步幅,扫描宽度,形象的说就是一行的长度。

4.PixelFormat:数据的实际像素格式。

给出原图:

 

一、灰度

对每个像素点进行加权平均,(方法不唯一)。

        /// <summary>/// 灰化实现方法/// </summary>void Image_Ashing(){if (pbshowbox.Image != null){int Height = this.pbshowbox.Image.Height;int Width = this.pbshowbox.Image.Width;Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);Bitmap MyBitmap = (Bitmap)this.pbshowbox.Image;BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);unsafe{byte* pin = (byte*)(oldData.Scan0.ToPointer());byte* pout = (byte*)(newData.Scan0.ToPointer());for (int y = 0; y < oldData.Height; y++){for (int x = 0; x < oldData.Width; x++){byte Result = (byte)(pin[0] * 0.1 + pin[1] * 0.2 + pin[2] * 0.7);//加权平均实现灰化pout[0] = (byte)(Result);pout[1] = (byte)(Result);pout[2] = (byte)(Result);pin = pin + 3;pout = pout + 3;}pin += oldData.Stride - oldData.Width * 3;pout += newData.Stride - newData.Width * 3;}bitmap.UnlockBits(newData);MyBitmap.UnlockBits(oldData);this.pbshowbox.Image = bitmap;}}else{MessageBox.Show("请先打开一张图片!");}}

二、柔化

像素点与周围像素点差别较大时取平均值。

        /// <summary>/// 柔化实现方法/// </summary>void Image_Soften(){if (pbshowbox.Image != null){int Height = this.pbshowbox.Image.Height;int Width = this.pbshowbox.Image.Width;Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format32bppRgb);Bitmap MyBitmap = (Bitmap)this.pbshowbox.Image;BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);unsafe{byte* pin = (byte*)(oldData.Scan0.ToPointer());byte* pout = (byte*)(newData.Scan0.ToPointer());//高斯模板int[] Gauss = { 1, 2, 1, 2, 4, 2, 1, 2, 1 };for (int i = 1; i < Width - 1; i++){for (int j = 1; j < Height - 1; j++){int r = 0, g = 0, b = 0;int Index = 0;for (int col = -1; col <= 1; col++){for (int row = -1; row <= 1; row++){int off = ((j + row) * (Width) + (i + col)) * 4;r += pin[off + 0] * Gauss[Index];g += pin[off + 1] * Gauss[Index];b += pin[off + 2] * Gauss[Index];Index++;}}r /= 16;g /= 16;b /= 16;//处理颜色值溢出if (r < 0) r = 0;if (r > 255) r = 255;if (g < 0) g = 0;if (g > 255) g = 255;if (b < 0) b = 0;if (b > 255) b = 255;int off2 = (j * Width + i) * 4;pout[off2 + 0] = (byte)r;pout[off2 + 1] = (byte)g;pout[off2 + 2] = (byte)b;}}bitmap.UnlockBits(newData);MyBitmap.UnlockBits(oldData);this.pbshowbox.Image = bitmap;}}else{MessageBox.Show("请先打开一张图片!");}}

三、锐化

突出显示颜色值大的像素点。

        /// <summary>/// 锐化实现方法,显示数值最大像素点/// </summary>void Image_Sharpen(){if (this.pbshowbox.Image != null){int Height = this.pbshowbox.Image.Height;int Width = this.pbshowbox.Image.Width;Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format32bppRgb);Bitmap MyBitmap = (Bitmap)this.pbshowbox.Image;BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);unsafe{byte* pin = (byte*)(oldData.Scan0.ToPointer());byte* pout = (byte*)(newData.Scan0.ToPointer());//拉普拉斯模板int[] Laplacian = { -1, -1, -1, -1, 9, -1, -1, -1, -1 };for (int i = 1; i < Width - 1; i++){for (int j = 1; j < Height - 1; j++){int r = 0, g = 0, b = 0;int Index = 0;for (int col = -1; col <= 1; col++){for (int row = -1; row <= 1; row++){int off = ((j + row) * (Width) + (i + col)) * 4;r += pin[off + 0] * Laplacian[Index];g += pin[off + 1] * Laplacian[Index];b += pin[off + 2] * Laplacian[Index];Index++;}}if (r < 0) r = 0;if (r > 255) r = 255;if (g < 0) g = 0;if (g > 255) g = 255;if (b < 0) b = 0;if (b > 255) b = 255;int off2 = (j * Width + i) * 4;pout[off2 + 0] = (byte)r;pout[off2 + 1] = (byte)g;pout[off2 + 2] = (byte)b;}}bitmap.UnlockBits(newData);MyBitmap.UnlockBits(oldData);this.pbshowbox.Image = bitmap;}}else{MessageBox.Show("请先打开一张图片!");}}

四、浮雕

对图像像素点的像素值分别与相邻像素点的像素值相减后加上128, 然后将其作为新的像素点的值。

        /// <summary>/// 浮雕实现方法/// </summary>void Image_Relief(){if (this.pbshowbox.Image != null){int Height = this.pbshowbox.Image.Height;int Width = this.pbshowbox.Image.Width;Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);Bitmap MyBitmap = (Bitmap)this.pbshowbox.Image;BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);unsafe{byte* pin_1 = (byte*)(oldData.Scan0.ToPointer());byte* pin_2 = pin_1 + (oldData.Stride);                byte* pout = (byte*)(newData.Scan0.ToPointer());for (int y = 0; y < oldData.Height - 1; y++){for (int x = 0; x < oldData.Width; x++){                           int b = (int)pin_1[0] - (int)pin_2[0] + 128;int g = (int)pin_1[1] - (int)pin_2[1] + 128;int r = (int)pin_1[2] - (int)pin_2[2] + 128;if (r < 0) r = 0;if (r > 255) r = 255;if (g < 0) g = 0;if (g > 255) g = 255;if (b < 0) b = 0;if (b > 255) b = 255;pout[0] = (byte)(b);pout[1] = (byte)(g);pout[2] = (byte)(r);pin_1 = pin_1 + 3;pin_2 = pin_2 + 3;pout = pout + 3;                          }pin_1 += oldData.Stride - oldData.Width * 3;pin_2 += oldData.Stride - oldData.Width * 3;pout += newData.Stride - newData.Width * 3;}bitmap.UnlockBits(newData);MyBitmap.UnlockBits(oldData);this.pbshowbox.Image = bitmap;}}else{MessageBox.Show("请先打开一张图片!");}}

五、底片

颜色值取反。

        /// <summary>/// 底片实现方法/// </summary>void Image_Negative(){if (pbshowbox.Image != null){int Height = this.pbshowbox.Image.Height;int Width = this.pbshowbox.Image.Width;Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);Bitmap MyBitmap = (Bitmap)this.pbshowbox.Image;BitmapData oldData = MyBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);unsafe{byte* pin = (byte*)(oldData.Scan0.ToPointer());byte* pout = (byte*)(newData.Scan0.ToPointer());for (int y = 0; y < oldData.Height; y++){for (int x = 0; x < oldData.Width; x++){pout[0] = (byte)(255 - pin[0]);pout[1] = (byte)(255 - pin[1]);pout[2] = (byte)(255 - pin[2]);pin = pin + 3;pout = pout + 3;}pin += oldData.Stride - oldData.Width * 3;pout += newData.Stride - newData.Width * 3;}bitmap.UnlockBits(newData);MyBitmap.UnlockBits(oldData);this.pbshowbox.Image = bitmap;}}else{MessageBox.Show("请先打开一张图片!");}}

六、积木

低像素置0,高像素置255。

        /// <summary>/// 积木实现方法/// </summary>private void Image_Block(){if (this.pbshowbox.Image != null){int Height = this.pbshowbox.Image.Height;int Width = this.pbshowbox.Image.Width;Bitmap bitmap = new Bitmap(Width, Height);Bitmap Mybitmap = (Bitmap)this.pbshowbox.Image;BitmapData oldData = Mybitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);BitmapData newData = bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);unsafe{byte* pin = (byte*)(oldData.Scan0.ToPointer());byte* pout = (byte*)(newData.Scan0.ToPointer());for (int y = 0; y < oldData.Height; y++){for (int x = 0; x < oldData.Width; x++){int avg = (pin[0] + pin[1] + pin[2]) / 3;if (avg > 128){pout[0] = 255;pout[1] = 255;pout[2] = 255;}else{pout[0] = 0;pout[1] = 0;pout[2] = 0;}pin = pin + 3;pout = pout + 3;}pin = pin + oldData.Stride - oldData.Width * 3;pout = pout + newData.Stride - newData.Width * 3;}bitmap.UnlockBits(newData);Mybitmap.UnlockBits(oldData);this.pbshowbox.Image = bitmap;}}else{MessageBox.Show("请先打开一张图片!");}}

有些图片效果看起来不明显是因为笔者把图缩小了,其实效果挺明显的- -。

 

转载于:https://www.cnblogs.com/zjc0202/p/4398605.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/291538.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql分组查询和子查询语句_6.MySQL分组聚合查询,子查询

自己的MySQL阅读笔记&#xff0c;持续更新&#xff0c;直到看书结束。数据库技术可以有效帮助一个组织或者企业科学、有效的管理数据&#xff0c;也是现在很多企业招聘数据分析师的必备要求之一。大家如果看过MySQL的书&#xff0c;也可以看我的知识导图做一个复习&#xff0c;…

ABP vNext微服务架构详细教程——分布式权限框架(下)

3公共组件添加公共类库Demo.Permissions&#xff0c;编辑Demo.Permissions.csproj文件&#xff0c;将 <Project Sdk"Microsoft.NET.Sdk"> 改为&#xff1a;<Project Sdk"Microsoft.NET.Sdk.Web">为Demo.Permissions项目添加Nuget引用Volo.Abp.…

ios开发第一步--虚拟机安装MAC OS X

暂时还没买Macbook&#xff0c;先用虚拟机练练手。 先说说准备工作&#xff0c;我是在win8下安装的&#xff0c;这个不是关键的&#xff0c;只要Vmware版本和MAC OS X版本确定就行了&#xff0c;win7下同样可以。 1、虚拟机Vmware10.0.0 下载地址 http://pan.baidu.com/s/1jGv…

算法学习笔记(三)-----各种基础排序问题

2019独角兽企业重金招聘Python工程师标准>>> 一、直接插入排序&#xff1a;是最简单的排序方法&#xff0c;算法简单来说就是可以把第一个数a[0]看做有序数组&#xff0c;那么a[1]要插入进来&#xff0c;对比&#xff0c;插入合适位置&#xff1b;然后a[0],a[1]是有…

mac之把打开终端设置快捷键为Ctrl+Alt+T

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程 1、在Automator.app中创建一个AppleScript Finder&#xff0d;>应用程序->Automator打开Automator.app&#xff0c;打开Automator后…

基础磁盘管理

一、设备文件Linux中设备类型分为字符设备与块设备&#xff0c;他们特点分别为&#xff1a;块设备特性&#xff1a;以“块”为单位进行存取&#xff0c;随机访问&#xff0c;例如磁盘字符设备特性&#xff1a;以“字节”单位进行存取&#xff0c;线性访问&#xff0c;例如键盘设…

HTML5 Canvas 画纸飞机组件

纸飞机模拟一个物体在规定设计轴线偏离方位。 1 //三角形2 function DrawTriangle(canvas, A, B, C) {3 //画个三角形,“A、B、C”是顶点4 with (canvas) {5 moveTo(A[0], A[1]);6 lineTo(B[0], B[1]);7 lineTo(C[0], C[1]);8 lineTo(…

OPPO R9凭创新赢得2000万销量,成2016年热销手机

2016年的手机市场虽然新闻不断但是整体状况并没有以往那么好&#xff0c;各方数据显示&#xff0c;2016年全年全球智能型手机出货量仅有2.3%的微幅增长&#xff0c;虽然中国市场的全年出货量通同比增长6%&#xff0c;但是比往年也大有不如&#xff0c;手机市场已从增量市场进入…

windows7 nginx php mysql_windows7配置Nginx+php+mysql的详细教程

最近在学习php&#xff0c;想把自己的学习经历记录下来&#xff0c;并写一些经验&#xff0c;仅供参考交流。此文适合那些刚刚接触php&#xff0c;想要学习并想要自己搭建Nginxphpmysql环境的同学。当然&#xff0c;你也可以选择集成好的安装包&#xff0c;比如 wamp等&#xf…

基于C#的计时管理器

问题我们使用各种系统时候会遇到以下问题&#xff1a;12306上购买火车票如果15分钟内未完成支付则订单自动取消。会议场馆预定座位&#xff0c;如果10分钟内未完成支付则预定自动取消。在指定时间之后&#xff0c;我需要执行一项任务。我之前做的很多系统&#xff0c;往往都是定…

HDU 2516 (Fabonacci Nim) 取石子游戏

这道题的结论就是&#xff0c;石子的个数为斐波那契数列某一项的时候&#xff0c;先手必败&#xff1b;否则&#xff0c;先手必胜。 结论很简单&#xff0c;但是证明却不是特别容易。找了好几篇博客&#xff0c;发现不一样的也就两篇&#xff0c;但是这两篇给的证明感觉证得不清…

access的ole对象换成mysql_ACCESS的Ole对象读取写入

Ole对象在Access中存储为二进制文件&#xff0c;读取的时候需要注意转换出的文件的编码格式1OleDbConnection OleConnnewOleDbConnection();2OleConn.ConnectionString"ProviderMicrosoft.Jet.OleDb.4.0;data sourceD:\WorkStation\Dialy_Sol\Dialy\Dialy.mdb";3OleD…

ABP vNext微服务架构详细教程——分布式权限框架(上)

1简介ABP vNext框架本身提供了一套权限框架&#xff0c;其功能非常丰富&#xff0c;具体可参考官方文档&#xff1a;https://docs.abp.io/en/abp/latest/Authorization但是我们使用时会发现&#xff0c;对于正常的单体应用&#xff0c;ABP vNext框架提供的权限系统没有问题&…

前端每隔几秒发送一个请求

2019独角兽企业重金招聘Python工程师标准>>> <html><head><SCRIPT LANGUAGE"JavaScript"> var timer;//声明一个定时器 var count 0; function test() { //每隔500毫秒执行一次add()方法 timer window.setInterval("add()"…

element 表单回显验证_关于vue el-form表单报错的问题

在写el-form表单的时候&#xff0c;遇到了蛮多问题&#xff0c;在这里记录一下。1.表单验证报错[Element Warn][Form]model is required for validate to work!初始代码如下&#xff1a;<!-- 表单部分 --> <el-formref"inputForm"size"mini"inlin…

我做了一个 Istio Workshop,这是第一讲介绍

我是 Jimmy Song[1]&#xff0c;Tetrate 布道师&#xff0c;云原生社区创始人。你可以能想到为什么在这个时候创建一个 Istio 教程&#xff0c;因为市面上已经林林总总有不少关于 Istio 的书籍和教程了&#xff0c;但是我们都知道 Istio 是一个新兴技术&#xff0c;发展十分迅速…

Swoole入门指南:PHP7安装Swoole详细教程(一)

好久未更新了&#xff0c;不是懒呃&#xff0c;是太忙啦&#xff01;终于偷得浮生几日闲。这一段时间准备为大家带来swoole的入门教程&#xff0c;感受一下php的nodeJs强悍之处。 所有的示例代码均放在了github上&#xff1a;learn-swoole 环境 这里不在使用apache做为web serv…

C/C++之#ifdef、#if、#if defined的区别

1、看代码 2、运行结果 3、分析 #fi&#xff1a;后面接的表达式&#xff0c;如果为1就编译包含里面的内容 #ifdef&#xff1a;后面接的是一个宏&#xff0c;只要定义这个宏就行 #if defined(x)&#xff1a;和#ifdef效果一样 #if !defined(x)&#xff1a;和#ifndef效果一样

.Net Core 读取文件时中文乱码问题的解决方法

背景今天在使用core web api上传txt文档的时候本来很顺利的&#xff0c;但是一测试发现读取的中文内容是乱码的&#xff0c;很是纳闷。出于经验&#xff0c;立马把代码的Encoding.Default改成 Encoding.uft8, 发现还是不行。后面索性把上传的文件另存为下&#xff0c;特地选择带…

关于使用indexedDB的本地存储(2)

我又回来了~这几天估计没喝茶&#xff0c;每天头都晕晕的&#xff0c;昨晚上和室友看了素鸡7&#xff0c;伤心啊&#xff0c;自己一直都喜欢这个系列&#xff0c;感觉童年真的是渐行渐远了…… 上一篇说到了哪些内容我这里罗列一下 建立和打开数据库、删除数据库、判断objectSt…