C# Bitmap图片GetPixel 和 SetPixel 效率问题
2021-03-05 10:26
标签:数据 color start gre throw 像素 更新 idt safe 在对Bitmap图片操作的时候,有时需要用到获取或设置像素颜色方法:GetPixel 和 SetPixel, 如果直接对这两个方法进行操作的话速度很慢,这里我们可以通过把数据提取出来操作,然后操作完在复制回去可以加快访问速度 其实对Bitmap的访问还有两种方式,一种是内存法,一种是指针法 1、内存法 这里定义一个类LockBitmap,通过把Bitmap数据拷贝出来,在内存上直接操作,操作完成后在拷贝到Bitmap中 使用方法这里就不列出来了,跟上面的LockBitmap类似 C# Bitmap图片GetPixel 和 SetPixel 效率问题 标签:数据 color start gre throw 像素 更新 idt safe 原文地址:https://www.cnblogs.com/ybqjymy/p/12897892.html 1 public class LockBitmap
2 {
3 Bitmap source = null;
4 IntPtr Iptr = IntPtr.Zero;
5 BitmapData bitmapData = null;
6
7 public byte[] Pixels { get; set; }
8 public int Depth { get; private set; }
9 public int Width { get; private set; }
10 public int Height { get; private set; }
11
12 public LockBitmap(Bitmap source)
13 {
14 this.source = source;
15 }
16
17 ///
使用:先锁定Bitmap,然后通过Pixels操作颜色对象,最后释放锁,把数据更新到Bitmap中
1 string file = @"C:\test.jpg";
2 Bitmap bmp = new Bitmap(Image.FromFile(file));
3
4 LockBitmap lockbmp = new LockBitmap(bmp);
5 //锁定Bitmap,通过Pixel访问颜色
6 lockbmp.LockBits();
7
8 //获取颜色
9 Color color = lockbmp.GetPixel(10, 10);
10
11 //从内存解锁Bitmap
12 lockbmp.UnlockBits();
2、指针法
这种方法访问速度比内存法更快,直接通过指针对内存进行操作,不需要进行拷贝,但是在C#中直接通过指针操作内存是不安全的,所以需要在代码中加入unsafe关键字,在生成选项中把允许不安全代码勾上,才能编译通过
这里定义成PointerBitmap类
1 public class PointBitmap
2 {
3 Bitmap source = null;
4 IntPtr Iptr = IntPtr.Zero;
5 BitmapData bitmapData = null;
6
7 public int Depth { get; private set; }
8 public int Width { get; private set; }
9 public int Height { get; private set; }
10
11 public PointBitmap(Bitmap source)
12 {
13 this.source = source;
14 }
15
16 public void LockBits()
17 {
18 try
19 {
20 // Get width and height of bitmap
21 Width = source.Width;
22 Height = source.Height;
23
24 // get total locked pixels count
25 int PixelCount = Width * Height;
26
27 // Create rectangle to lock
28 Rectangle rect = new Rectangle(0, 0, Width, Height);
29
30 // get source bitmap pixel format size
31 Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);
32
33 // Check if bpp (Bits Per Pixel) is 8, 24, or 32
34 if (Depth != 8 && Depth != 24 && Depth != 32)
35 {
36 throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");
37 }
38
39 // Lock bitmap and return bitmap data
40 bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,
41 source.PixelFormat);
42
43 //得到首地址
44 unsafe
45 {
46 Iptr = bitmapData.Scan0;
47 //二维图像循环
48
49 }
50 }
51 catch (Exception ex)
52 {
53 throw ex;
54 }
55 }
56
57 public void UnlockBits()
58 {
59 try
60 {
61 source.UnlockBits(bitmapData);
62 }
63 catch (Exception ex)
64 {
65 throw ex;
66 }
67 }
68
69 public Color GetPixel(int x, int y)
70 {
71 unsafe
72 {
73 byte* ptr = (byte*)Iptr;
74 ptr = ptr + bitmapData.Stride * y;
75 ptr += Depth * x / 8;
76 Color c = Color.Empty;
77 if (Depth == 32)
78 {
79 int a = ptr[3];
80 int r = ptr[2];
81 int g = ptr[1];
82 int b = ptr[0];
83 c = Color.FromArgb(a, r, g, b);
84 }
85 else if (Depth == 24)
86 {
87 int r = ptr[2];
88 int g = ptr[1];
89 int b = ptr[0];
90 c = Color.FromArgb(r, g, b);
91 }
92 else if (Depth == 8)
93 {
94 int r = ptr[0];
95 c = Color.FromArgb(r, r, r);
96 }
97 return c;
98 }
99 }
100
101 public void SetPixel(int x, int y, Color c)
102 {
103 unsafe
104 {
105 byte* ptr = (byte*)Iptr;
106 ptr = ptr + bitmapData.Stride * y;
107 ptr += Depth * x / 8;
108 if (Depth == 32)
109 {
110 ptr[3] = c.A;
111 ptr[2] = c.R;
112 ptr[1] = c.G;
113 ptr[0] = c.B;
114 }
115 else if (Depth == 24)
116 {
117 ptr[2] = c.R;
118 ptr[1] = c.G;
119 ptr[0] = c.B;
120 }
121 else if (Depth == 8)
122 {
123 ptr[2] = c.R;
124 ptr[1] = c.G;
125 ptr[0] = c.B;
126 }
127 }
128 }
129 }
文章标题:C# Bitmap图片GetPixel 和 SetPixel 效率问题
文章链接:http://soscw.com/index.php/essay/60396.html