以Lockbits的方式访问bitmap
转载自:http://www.cnblogs.com/xiashengwang/p/4225848.html
2015-01-15 11:38 by xiashengwang, 585 阅读, 0 评论, 收藏, 编辑
用Bitmap.GetPixel和Bitmap.SetPixel访问像素点实在是太慢了,必须要用LockBits的方式访问内存才能改善,这里贴一个快速访问Bitmap每个像素点的包装类,是国外一个老外写的,感觉很好用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
public class LockBitmap { Bitmap source = null ; IntPtr Iptr = IntPtr.Zero; BitmapData bitmapData = null ; public byte [] Pixels { get ; set ; } public int Depth { get ; private set ; } public int Width { get ; private set ; } public int Height { get ; private set ; } public LockBitmap(Bitmap source) { this .source = source; } /// <summary> /// Lock bitmap data /// </summary> public void LockBits() { try { // Get width and height of bitmap Width = source.Width; Height = source.Height; // get total locked pixels count int PixelCount = Width * Height; // Create rectangle to lock System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, Width, Height); // get source bitmap pixel format size Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat); // Check if bpp (Bits Per Pixel) is 8, 24, or 32 if (Depth != 8 && Depth != 24 && Depth != 32) { throw new ArgumentException( "Only 8, 24 and 32 bpp images are supported." ); } // Lock bitmap and return bitmap data bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite, source.PixelFormat); // create byte array to copy pixel values int step = Depth / 8; Pixels = new byte [PixelCount * step]; Iptr = bitmapData.Scan0; // Copy data from pointer to array Marshal.Copy(Iptr, Pixels, 0, Pixels.Length); } catch (Exception ex) { throw ex; } } /// <summary> /// Unlock bitmap data /// </summary> public void UnlockBits() { try { // Copy data from byte array to pointer Marshal.Copy(Pixels, 0, Iptr, Pixels.Length); // Unlock bitmap data source.UnlockBits(bitmapData); } catch (Exception ex) { throw ex; } } /// <summary> /// Get the color of the specified pixel /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public Color GetPixel( int x, int y) { Color clr = Color.Empty; // Get color components count int cCount = Depth / 8; // Get start index of the specified pixel int i = ((y * Width) + x) * cCount; if (i > Pixels.Length - cCount) throw new IndexOutOfRangeException(); if (Depth == 32) // For 32 bpp get Red, Green, Blue and Alpha { byte b = Pixels[i]; byte g = Pixels[i + 1]; byte r = Pixels[i + 2]; byte a = Pixels[i + 3]; // a clr = Color.FromArgb(a, r, g, b); } if (Depth == 24) // For 24 bpp get Red, Green and Blue { byte b = Pixels[i]; byte g = Pixels[i + 1]; byte r = Pixels[i + 2]; clr = Color.FromArgb(r, g, b); } if (Depth == 8) // For 8 bpp get color value (Red, Green and Blue values are the same) { byte c = Pixels[i]; clr = Color.FromArgb(c, c, c); } return clr; } /// <summary> /// Set the color of the specified pixel /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="color"></param> public void SetPixel( int x, int y, Color color) { // Get color components count int cCount = Depth / 8; // Get start index of the specified pixel int i = ((y * Width) + x) * cCount; if (Depth == 32) // For 32 bpp set Red, Green, Blue and Alpha { Pixels[i] = color.B; Pixels[i + 1] = color.G; Pixels[i + 2] = color.R; Pixels[i + 3] = color.A; } if (Depth == 24) // For 24 bpp set Red, Green and Blue { Pixels[i] = color.B; Pixels[i + 1] = color.G; Pixels[i + 2] = color.R; } if (Depth == 8) // For 8 bpp set color value (Red, Green and Blue values are the same) { Pixels[i] = color.B; } } public bool IsValidCoordinate( int x, int y) { return x >= 0 && x < this .Width && y > 0 && y < this .Height; } } |
还有一个时间测算的类,可以计算代码的时间差,跟Stopwatch差不多
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class Benchmark { private static DateTime startDate = DateTime.MinValue; private static DateTime endDate = DateTime.MinValue; public static TimeSpan Span { get { return endDate.Subtract(startDate); } } public static void Start() { startDate = DateTime.Now; } public static void End() { endDate = DateTime.Now; } public static double GetSeconds() { if (endDate == DateTime.MinValue) return 0.0; else return Span.TotalSeconds; } } |
以Lockbits的方式访问bitmap的更多相关文章
- Linux实现https方式访问站点
超文本传送协议(HyperText Transfer Protocol,HTML)是一种通信协议,它允许将超文本标记语言文档从web服务器传送到wel浏览器. HTML的特点: 1.支持客户/服务器模 ...
- SharePoint—用REST方式访问列表
REST的定义与作用 在SharePoint 2010中,基本上有如下几种数据访问方式: 服务器端对象模型 LINQ to SharePoint Web Service 客户端对象模型 ADO.NET ...
- salesforce 零基础学习(三十三)通过REST方式访问外部数据以及JAVA通过rest方式访问salesforce
本篇参考Trail教程: https://developer.salesforce.com/trailhead/force_com_dev_intermediate/apex_integration_ ...
- 非链接方式访问数据库--查询的数据集用Dataset来存储。
private void Button_Click_1(object sender, RoutedEventArgs e) { //非链接方式访问数据库, //1创建连接对象(连接字符串) using ...
- ADO.NET 连接方式和非链接方式访问数据库
一.//连接方式访问数据库的主要步骤(利用DataReader对象实现数据库连接模式) 1.创建连接对象(连接字符串) SqlConnection con = new SqlConnection(Co ...
- httpclient 认证方式访问http api/resutful api并获取json结果
最近,因公司线上环境rabbitmq经常发生堆积严重的现象,于是跟运维组讨论,帮助开发个集中监控所有rabbitmq服务器运行情况的应用,需要通过java访问rabbitmq暴露的http api并接 ...
- php 面向对象的方式访问数据库
<body> <?php //面向对象的方式访问数据库 //造对象 $db = new MySQLi("localhost","root",& ...
- URL方式访问Hadoop的内容
* 1.设置url支持hadoop,FsUrlStreamHandlerFactory * 2.创建URL对象,指定访问的HDFS路径 * 3.openStream获取输入流对象, ...
- 使用HttpWebRequest方式访问外部接口
第一步,如果不是http网站,则需认证信托证书 /// <summary> /// 认证信托证书 /// </summary> /// <param name=" ...
随机推荐
- 在PHP应用中简化OAuth2.0身份验证集成:OAuth 2.0 Client
在PHP应用中简化OAuth2.0身份验证集成:OAuth 2.0 Client 阅读目录 验证代码流程 Refreshing a Token Built-In Providers 这个包能够让你 ...
- php 导出csv
public function doworks(){ //输出Excel文件头,可把user.csv换成你要的文件名 header('Content-Type: appli ...
- 基于s5pv210嵌入式linux系统sqlite3数据库移植
基于s5pv210嵌入式linux系统sqlite3数据库移植 1.下载源码 http://www.sqlite.org/download.html 最新源码为3080100 2.解压 tar xvf ...
- SpringMVC与HTML页面
springMVC返回html页面 spring-mvc.xml配置: <bean id="viewResolver" class="org.springfram ...
- 分享一个jquery写的类似于百度的搜索框,(可动态配置,可单列或者table格式,可填充数据)
需求:类似于百度的搜索框,可配置,可单列可table格式,可填充数据.页面可多次使用,简单,易用. 想法:使用jquery,css,ajax,前台调用,后台返回json数据. jquery代码: va ...
- 【转】Javascript 严格模式详解
ref: http://www.ruanyifeng.com/blog/2013/01/javascript_strict_mode.html 一.概述 除了正常运行模式,ECMAscript 5添加 ...
- "/Date(1405056837780)/" 时间转换
//往往json传过来的时间都是"/Date(1405056837780)/" //转换需要的方法 String.prototype.ToString = function (fo ...
- Cassandra 之 入门
1.到官网下载压缩包. http://cassandra.apache.org/download/ 我下载的是最新的 apache-cassandra-2.1.2-bin.tar.gz 另外:语言支持 ...
- js数组的内部实现,迭代器,生成器和内包
js内部实现 在js以外的很多语言中,数组将会隐式占用一段连续的内存空间.这种隐式的内部实现,使得高效的内存使用及高速的元素方法称为可能,而 在javascript中,数组实体是一个对象,所以通常的实 ...
- php 安装xdebug扩展
php 扩展获取地址 http://pecl.php.net/package/ 编译安装的过程 wget http://pecl.php.net/get/xdebug-2.2.2.tgz tar -z ...