一:图片灰度化 我们都知道

时间:2021-12-24 08:58:46

去年买了本数字图像措置惩罚惩罚算法,一直都没有看,前几个星期都一直忙着事情上的活,趁这阶段悠闲点,玩一玩图片措置惩罚惩罚,这玩意还长短常有意思的。

以前我们在做Web上的用户注册时,凡是城市做一个验证码,大家都知道用来防备暴力注册的,固然提到验证码大家都知道C#里面有一个Bitmap类专门用来措置惩罚惩罚图片的,好吧,这一篇我们从最简单的“图片灰度化”说起。


一:图片灰度化

我们都知道,位图是由一个一个像素点构成的,像素点可能是红色,橙色,粉色等等,这些颜色我们都知道是用RGB来暗示的。

每个颜色分量都是一个字节(0-255),所以一般情况下图的像素点都是24位,固然还有32位,64位,当RGB是0-255之间的差别值时,那么该像素点就泛起“五颜六色”,而当RGB都是不异的值是,则像素点泛起“灰色”,如果大家玩过CSS的话,必建都知道给一个字体的color凡是都是#999999,#666666,#333333这些差别深度的灰色。


1.计算公式

下面我们该如何设置合理的灰度值呢?固然还是用当前的RGB为模板,然后对RGB乘以一个合理的权重就ok了


代码如下:


Gary(i,j)=0.299*R(i,j)+0.587*G(i,j)+0.114*B(i,j);


2.编程

有了公式,实现起来就弗成问题了。Bitmap类中有一个GetPixel/SetPixel,它可以获取和设置当前的像素点。

static void Main(string[] args) { Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "//1.jpg"); for (int i = 0; i < bitmap.Width; i++) { for (int j = 0; j < bitmap.Height; j++) { //取图片当前的像素点 var color = bitmap.GetPixel(i, j); var gray = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114); //从头设置当前的像素点 bitmap.SetPixel(i, j, Color.FromArgb(gray, gray, gray)); } } bitmap.Save(Environment.CurrentDirectory + "//2.jpg"); }

一:图片灰度化 我们都知道


3.改造

上面这个要领很简单,Get/Set就Ok了,固然这是我们站在像素点这个角度来考虑问题的,貌似只要O(N2)的时间就可以KO问题,但是Get/Set远远不是O(1)的,基于性能考虑,我们能不能有更优的要领,此时我们可以站在字节这个角度思考,,不过这里我们要注意一个问题就是:好比图片的width=21px,一个像素点占用3个字节,但是21个像素点不必然就占用63个字节,这是因为系统基于性能考虑,在每一行中存放着一个“未用区域”,来确保图片每行的byte数是4的倍数,那么如何去读某一行的字节数呢?

C#里面有一个Stride属性就可以用来获取,很简单吧。

static void Main(string[] args) { Bitmap bitmap = new Bitmap(Environment.CurrentDirectory + "//1.jpg"); //界说锁定bitmap的rect的指定范畴区域 Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height); //加锁区域像素 var bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat); //位图的首地点 var ptr = bitmapData.Scan0; //stride:扫描行 int len = bitmapData.Stride * bitmap.Height; var bytes = new byte[len]; //锁定区域的像素值copy到byte数组中 Marshal.Copy(ptr, bytes, 0, len); for (int i = 0; i < bitmap.Height; i++) { for (int j = 0; j < bitmap.Width * 3; j = j + 3) { var color = bytes[i * bitmapData.Stride + j + 2] * 0.299 + bytes[i * bitmapData.Stride + j + 1] * 0.597 + bytes[i * bitmapData.Stride + j] * 0.114; bytes[i * bitmapData.Stride + j] = bytes[i * bitmapData.Stride + j + 1] = bytes[i * bitmapData.Stride + j + 2] = (byte)color; } } //copy回位图 Marshal.Copy(bytes, 0, ptr, len); //解锁 bitmap.UnlockBits(bitmapData); bitmap.Save(Environment.CurrentDirectory + "//3.jpg"); }

一:图片灰度化 我们都知道