博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
以Lockbits的方式访问bitmap
阅读量:6253 次
发布时间:2019-06-22

本文共 4692 字,大约阅读时间需要 15 分钟。

转载自: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;
    
}
}

转载于:https://www.cnblogs.com/qidaiymm/p/4956072.html

你可能感兴趣的文章
Protocol Buffer技术详解(数据编码)
查看>>
【javascript】ajax 基础
查看>>
2015 UESTC 搜索专题N题 韩爷的梦 hash
查看>>
MySQL 二进制日志过滤
查看>>
Centos下Tomcat 安装Apache Portable Runtime
查看>>
【BZOJ】2563: 阿狸和桃子的游戏
查看>>
redis 中文字符显示
查看>>
webview与JS的交互
查看>>
吴翼大神
查看>>
在Gridview如何进行每行单元格比较
查看>>
国内外MD5在线解密网站
查看>>
插件五之滚动条jquery.slimscroll.js
查看>>
187实现录制视频功能
查看>>
教你pomeloclient包libpomelo增加cocos2d-x 3.0工程(Windows、Android、IOS平台)
查看>>
CSS3实现时间轴效果
查看>>
经典回忆Effective C++ 1
查看>>
JQUERY名称冲突
查看>>
poj 1975 Median Weight Bead(传递闭包 Floyd)
查看>>
【C++ Primer每天刷牙】一间 迭代器
查看>>
:施密特建议尾随年轻的专业人士了解技术公司
查看>>