




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、c#图像处理入门的一个好方法 c#图像处理入门的一个好方法-bitmap类和图像像素值获取方法 一Bitmap类Bitmap对象封装了+中的一个位图,此位图由图形图像及其属性的像素数据组成.因此Bitmap是用于处理由像素数据定义的图像的对象.该类的主要方法和属性如下:1. GetPixel方法和 SetPixel方法:获取和设置一个图像的指定像素的颜色.2. PixelFormat属性:返回图像的像素格式.3. Palette属性:获取和设置图像所使用的颜色调色板.4. Height Width属性:返回图像的高度和宽度.5. LockBits 方法和UnlockBits方法:分别锁定和解锁
2、系统内存中的位图像素.在基于像素点的图像处理方法中使用LockBits 和UnlockBits是一个很好的方式,这两种方法可以使我们指定像素的范围来控制位图的任意一部分,从而消除了通过循环对位图的像素逐个进行处理,每调用LockBits 之后都应该调用一次UnlockBits. 二BitmapData类BitmapData对象指定了位图的属性1. Height属性:被锁定位图的高度.2. Width属性:被锁定位图的高度.3. PixelFormat属性:数据的实际像素格式.4. Scan0属性:被锁定数组的首字节地址,如果整个图像被锁定,则是图像的第一个字节地址.5. Stride属性:步幅
3、,也称为扫描宽度.如上图所示,数组的长度并不一定等于图像像素数组的长度,还有一部分未用区域,这涉及到位图的数据结构,系统要保证每行的字节数必须为4的倍数. 三Graphics类Graphics对象是+的关键所在,许多对象都是由Graphics类表示的,该类定义了绘制和填充图形对象的方法和属性,一个应用程序只要需要进行绘制或着色,它就必须使用Graphics对象. 四Image类这个类提供了位图和元文件操作的函数.Image类被声明为abstract,也就是说Image类不能实例化对象,而只能做为一个基类.1.FromFile方法:它根据输入的文件名产生一个Image对象,它有两种函数形式:pu
4、blic static Image FromFile(string filename);public static Image FromFile(string filename, bool useEmbeddedColorManagement);2.FromHBitmap方法:它从一个windows句柄处创建一个bitmap对象, 它也包括两种函数形式:public static bitmap fromhbitmap(intptr hbitmap);public static bitmap fromhbitmap(intptr hbitmap, intptr hpalette);3. From
5、Stream方法:从一个数据流中创建一个image对象,它包含三种函数形式 :public static image fromstream(stream stream);public static image fromstream(stream stream, bool useembeddedcolormanagement);fromstream(stream stream, bool useembeddedcolormanagement, bool validateimagedata); 有了上面的了解,我们便可以开始利用#做图像处理,下面介绍几种方法:一. 打开、保存、显示图像 priva
6、te Bitmap srcBitmap = null; private Bitmap showBitmap = null; /打开文件 private void menuFileOpen_Click(object sender, EventArgs e) OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;*.jpg" openFile
7、Dialog.FilterIndex = 3; openFileDialog.RestoreDirectory = true; if (DialogResult.OK = openFileDialog.ShowDialog() srcBitmap = (Bitmap)Bitmap.FromFile(openFileDialog.FileName, false); showBitmap = srcBitmap; this.AutoScroll = true; this.AutoScrollMinSize = new Size(int)(showBitmap.Width), (int)(showB
8、itmap.Height); this.Invalidate(); /保存图像文件 private void menuFileSave_Click(object sender, EventArgs e) if (showBitmap != null) SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.Filter = "Bitmap文件(*.bmp)|*.bmp|Jpeg文件(*.jpg)|*.jpg|所有合适文件(*.bmp,*.jpg)|*.bmp;*.jpg" saveFileDi
9、alog.FilterIndex = 3; saveFileDialog.RestoreDirectory = true; if (DialogResult.OK = saveFileDialog.ShowDialog() ImageFormat format = ImageFormat.Jpeg; switch (Path.GetExtension(saveFileDialog.FileName).ToLower() case ".jpg": format = ImageFormat.Jpeg; break; case ".bmp": format =
10、 ImageFormat.Bmp; break; default: MessageBox.Show(this, "Unsupported image format was specified", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; try showBitmap.Save(saveFileDialog.FileName,format ); catch (Exception) MessageBox.Show(this, "Failed writing image
11、 file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); /窗口重绘,在窗体上显示图像,重载Paint private void frmMain_Paint(object sender, System.Windows.Forms.PaintEventArgs e) if (showBitmap != null) Graphics g = e.Graphics; g.DrawImage(showBitmap, new Rectangle(this.AutoScrollPosition.X, this.
12、AutoScrollPosition.Y , (int)(showBitmap.Width), (int)(showBitmap.Height); /灰度化 private void menu2Gray_Click(object sender, EventArgs e) if (showBitmap = null) return; showBitmap = RGB2Gray(showBitmap);/下面都以RGB2Gray为例 this.Invalidate(); 二. 提取像素法 这种方法简单易懂,但相当耗时,完全不可取.public static Bitmap RGB2Gray(Bitm
13、ap srcBitmap) Color srcColor; int wide = srcBitmap.Width; int height = srcBitmap.Height; for (int y = 0; y < height; y+) for (int x = 0; x < wide; x+) /获取像素的颜色值 srcColor = srcBitmap.GetPixel(x, y); byte temp = (byte)(srcColor.R * .299 + srcColor.G * .587 + srcColor.B * .114); /设置像素的颜色值
14、 srcBitmap.SetPixel(x, y, Color.FromArgb(temp, temp, temp); return srcBitmap ; /# 三. 内存法这是比较常用的方法public static Bitmap RGB2Gray(Bitmap srcBitmap) int wide = srcBitmap.Width; int height = srcBitmap.Height; Rectangle rect = new Rectangle(0, 0, wide, height); / 将Bitmap锁定到系统内存中, 获得BitmapData BitmapData s
15、rcBmData = srcBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); /创建Bitmap Bitmap dstBitmap = CreateGrayscaleImage(wide, height);/这个函数在后面有定义 BitmapData dstBmData = dstBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); / 位图中第一个像素数据的地址。它也可以看成是位图中的第一
16、个扫描行 System.IntPtr srcPtr = srcBmData.Scan0; System.IntPtr dstPtr = dstBmData.Scan0; / 将Bitmap对象的信息存放到byte数组中 int src_bytes = srcBmData.Stride * height; byte srcValues = new bytesrc_bytes; int dst_bytes = dstBmData.Stride * height; byte dstValues = new bytedst_bytes; /复制GRB信息到byte数组 System.Runtime.I
17、nteropServices.Marshal.Copy(srcPtr, srcValues, 0, src_bytes); System.Runtime.InteropServices.Marshal.Copy(dstPtr, dstValues, 0, dst_bytes); / 根据Y=0.299*R+0.114*G+0.587B,Y为亮度 for (int i = 0; i < height; i+) for (int j = 0; j < wide; j+) /只处理每行中图像像素数据,舍弃未用空间 /注意位图结构中RGB按BGR的顺序存储 int k =
18、3 * j; byte temp = (byte)(srcValuesi * srcBmData.Stride + k + 2 * .299 + srcValuesi * srcBmData.Stride + k + 1 * .587 + srcValuesi * srcBmData.Stride + k * .114); dstValuesi * dstBmData.Stride + j = temp; /将更改过的byte拷贝到原位图 System.Runtime.InteropServices.Marshal.Copy(dstValues, 0, dstPtr, dst_bytes);
19、/ 解锁位图 srcBitmap.UnlockBits(srcBmData); dstBitmap.UnlockBits(dstBmData); return dstBitmap; /# 四 指针法C/C+的习惯,不是C#的特点public static Bitmap RGB2Gray(Bitmap srcBitmap) int wide = srcBitmap.Width; int height = srcBitmap.Height ; Rectangle rect = new Rectangle(0, 0, wide, height); BitmapData srcBmData = src
20、Bitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); Bitmap dstBitmap = CreateGrayscaleImage(wide, height); BitmapData dstBmData = dstBitmap.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); System.IntPtr srcScan = srcBmData.Scan0; System.IntPtr dstScan =
21、 dstBmData.Scan0; Unsafe /启动不安全代码 byte* srcP = (byte*)(void*) srcScan; byte* dstP = (byte*)(void*) dstScan; int srcOffset = srcBmData.Stride - wide * 3; int dstOffset = dstBmData.Stride - wide ; byte red, green, blue; for (int y = 0; y < height; y+) for (int x = 0; x <wide ; x+, srcP +
22、= 3, dstP+) blue = srcP 0; green = srcP 1; red = srcP 2; * dstP = (byte)(.299 * red + .587 * green + .114 * blue); srcP += srcOffset; dstP += dstOffset; srcBitmap.UnlockBits(srcBmData); dstBitmap.UnlockBits(dstBmData ); return dstBitmap; /#五. 矩阵法并不是什么新方法,只是将图像数据分做R,G,B三个矩阵(二维数组)存储,类似MATLAB的习惯. publi
23、c static bool GetRGB(Bitmap Source, out int, R, out int, G, out int, B) try int iWidth = Source.Width; int iHeight = Source.Height; Rectangle rect = new Rectangle(0, 0, iWidth, iHeight); System.Drawing.Imaging.BitmapData bmpData = Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite,
24、 Source.PixelFormat); IntPtr iPtr = bmpData.Scan0; int iBytes = iWidth * iHeight * 3; byte PixelValues = new byteiBytes; System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes); Source.UnlockBits(bmpData); / 注意这个地方图像的两维方向与数组两维的方向是转置的关系 R = new intiHeight, iWidth; G = new intiHeight
25、, iWidth; B = new intiHeight, iWidth; int iPoint = 0; for (int i = 0; i < iHeight; i+) for (int j = 0; j < iWidth; j+) / 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB! Bi, j = Convert.ToInt32(PixelValuesiPoint+); Gi, j = Convert.ToInt32(PixelValuesiPoint+); Ri, j = Convert.ToInt32(PixelValuesiPoin
26、t+); return true; catch (Exception) R = null; G = null; B = null; return false; /# public static Bitmap FromRGB(int, R, int, G, int, B) int iWidth = G.GetLength(1); int iHeight = G.GetLength(0); Bitmap Result = new Bitmap(iWidth, iHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb); Rectangle
27、 rect = new Rectangle(0, 0, iWidth, iHeight); System.Drawing.Imaging.BitmapData bmpData = Result.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb); IntPtr iPtr = bmpData.Scan0; int iStride = bmpData.Stride; int iBytes = iWidth * iHeight
28、 * 3; byte PixelValues = new byteiBytes; int iPoint = 0; for (int i = 0; i < iHeight; i+) for (int j = 0; j < iWidth; j+) int iG = Gi, j; int iB = Bi, j; int iR = Ri, j; PixelValuesiPoint = Convert.ToByte(iB); PixelValuesiPoint + 1 = Convert.ToByte(iG); PixelValuesiPoint + 2 = Convert.
29、ToByte(iR); iPoint += 3; System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes); Result.UnlockBits(bmpData); return Result; /# public static bool GetGray(Bitmap srcBitmap, out byte , gray) Bitmap tempBitmap; if (srcBitmap.PixelFormat != PixelFormat.Format8bppIndexed) tempBitmap =
30、ImageProcess.Image.Gray(srcBitmap); else tempBitmap = srcBitmap; int wide = tempBitmap.Width; int height = tempBitmap.Height; gray = new byte height, wide; BitmapData gbmData = tempBitmap.LockBits(new Rectangle(0, 0, wide, height), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); System.IntP
31、tr ScanG = gbmData.Scan0; int gOffset = gbmData.Stride - wide; unsafe byte* g = (byte*)(void*)ScanG; / for each pixel for (int y = 0; y < height; y+) / for each pixel for (int x = 0; x < wide; x+, g+) grayy ,x =*g; g += gOffset; tempBitmap.UnlockBits(gbmData); return true ; /# public s
32、tatic Bitmap FromGray(byte , Gray) int iWidth = Gray.GetLength(1); int iHeight = Gray.GetLength(0); Bitmap dstBitmap = ImageProcess.Image.CreateGrayscaleImage(iWidth, iHeight); BitmapData gbmData = dstBitmap.LockBits(new Rectangle(0, 0, iWidth, iHeight), ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); System.IntPtr ScanG = gbmData.Scan0; int gOffset = gbmData.Stri
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 五人散伙协议合同标准文本
- 中堂酒店蔬菜配送合同标准文本
- 2025年中储粮储运有限公司招聘(57人)笔试参考题库附带答案详解
- 2025国网重庆市电力公司校园招聘约85人(第一批)笔试参考题库附带答案详解
- 2025国网安徽省电力有限公司高校毕业生招聘约136人(第二批)笔试参考题库附带答案详解
- 2025中铁集装箱运输有限责任公司招聘46人(京外地区岗位)笔试参考题库附带答案详解
- 2025中国联通苍南县分公司招聘10人(浙江温州市)笔试参考题库附带答案详解
- 传统中医如何治疗小儿腹泻
- 2024浙江宁波市余姚市姚东自来水有限公司招聘笔试及人员笔试参考题库附带答案详解
- 2024旭和(天津)医药科技有限公司社会化公开选聘兽医岗笔试参考题库附带答案详解
- 医学资料 医院感染管理基本知识培训 学习课件
- 2025年山东高速集团总部部分业务技术岗位内部选聘9人自考难、易点模拟试卷(共500题附带答案详解)
- 模具单位年终工作总结
- 2025年考研护理面试试题及答案
- 人教版七年级历史下学期第一单元第2课时唐朝建立与“贞观之治”测试试题(含答案)
- 2025年第六届全国国家版图网络知识竞赛题库及答案(中小学组)
- 医护职业危害与防护知识
- 排泄照护为老年人更换尿布纸尿裤养老护理员课件
- 十八项核心制度培训课件
- 《深度学习原理》课程教学大纲
- 2025年山东大众报业(集团)限公司招聘247人高频重点模拟试卷提升(共500题附带答案详解)
评论
0/150
提交评论