详细解读Bitmap的优化

简介: 详细解读Bitmap的优化

摘自:

作者:Vano Maisuradze

  当你在C#中操作bitmaps时,你可以使用 GetPixel(x ,y) 和 SetPixel(x, y, color) 去获取/设置特定像素的值。但是它们十分的慢。

  这里有另一种更快的方法去操作bitmaps。

LockBitmap

  使用LockBitmap类,我们可以锁定/解锁bitmaps的数据

  (PS:这里定义一个类LockBitmap,锁定时把bitmap所有像素的数据拷贝在一个数组上,操作时就是在数组上直接操作,避免了对bitmap的直接操作,解锁后就拷贝回到bitmap中。)

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 ///

18 /// Lock bitmap data

19 ///

20 public void LockBits()

21 {

22 try

23 {

24 // Get width and height of bitmap

25 Width = source.Width;

26 Height = source.Height;

27

28 // get total locked pixels count

29 int PixelCount = Width Height;

30

31 // Create rectangle to lock

32 Rectangle rect = new Rectangle(0, 0, Width, Height);

33

34 // get source bitmap pixel format size

35 Depth = System.Drawing.Bitmap.GetPixelFormatSize(source.PixelFormat);

36

37 // Check if bpp (Bits Per Pixel) is 8, 24, or 32

38 if (Depth != 8 Depth != 24 Depth != 32)

39 {

40 throw new ArgumentException("Only 8, 24 and 32 bpp images are supported.");

41 }//代码效果参考:http://www.ezhiqi.com/zx/art_5014.html

42

43 // Lock bitmap and return bitmap data

44 bitmapData = source.LockBits(rect, ImageLockMode.ReadWrite,

45 source.PixelFormat);

46

47 // create byte array to copy pixel values

48 int step = Depth / 8;

49 Pixels = new byte【PixelCount step】;

50 Iptr = bitmapData.Scan0;

51

52 // Copy data from pointer to array

53 Marshal.Copy(Iptr, Pixels, 0, Pixels.Length);

54 }

55 catch (Exception ex)

56 {

57 throw ex;

58 }

59 }

60

61 ///

62 /// Unlock bitmap data

63 ///

64 public void UnlockBits()

65 {

66 try

67 {

68 // Copy data from byte array to pointer

69 Marshal.Copy(Pixels, 0, Iptr, Pixels.Length);

70

71 // Unlock bitmap data

72 source.UnlockBits(bitmapData);

73 }

74 catch (Exception ex)

75 {

76 throw ex;

77 }

78 }

79

80 ///

81 /// Get the color of the specified pixel

82 ///

83 ///

84 ///

85 ///

86 public Color GetPixel(int x, int y)

87 {

88 Color clr = Color.Empty;

89

90 // Get color components count

91 int cCount = Depth / 8;

92

93 // Get start index of the specified pixel

94 int i = ((y Width) + x) cCount;

95

96 if (i > Pixels.Length - cCount)

97 throw new IndexOutOfRangeException();

98

99 if (Depth == 32) // For 32 bpp get Red, Green, Blue and Alpha

100 {

101 byte b = Pixels【i】;

102 byte g = Pixels【i + 1】;

103 byte r = Pixels【i + 2】;

104 byte a = Pixels【i + 3】; // a

105 clr = Color.FromArgb(a, r, g, b);

106 }

107 if (Depth == 24) // For 24 bpp get Red, Green and Blue

108 {

109 byte b = Pixels【i】;

110 byte g = Pixels【i + 1】;

111 byte r = Pixels【i + 2】;

112 clr = Color.FromArgb(r, g, b);

113 }

114 if (Depth == 8)

115 // For 8 bpp get color value (Red, Green and Blue values are the same)

116 {

117 byte c = Pixels【i】;

118 clr = Color.FromArgb(c, c, c);

119 }

120 return clr;

121 }

122

123 ///

124 /// Set the color of the specified pixel

125 ///

126 ///

127 ///

128 ///

129 public void SetPixel(int x, int y, Color color)

130 {

131 // Get color components count

132 int cCount = Depth / 8;

133

134 // Get start index of the specified pixel

135 int i = ((y Width) + x) cCount;

136

137 if (Depth == 32) // For 32 bpp set Red, Green, Blue and Alpha

138 {

139 Pixels【i】 = color.B;

140 Pixels【i + 1】 = color.G;

141 Pixels【i + 2】 = color.R;

142 Pixels【i + 3】 = color.A;

143 }

144 if (Depth == 24) // For 24 bpp set Red, Green and Blue

145 {

146 Pixels【i】 = color.B;

147 Pixels【i + 1】 = color.G;

148 Pixels【i + 2】 = color.R;

149 }

150 if (Depth == 8)

151 // For 8 bpp set color value (Red, Green and Blue values are the same)

152 {

153 Pixels【i】 = color.B;

154 }

155 }

156 }

测试方法

  我们可以使用Benchmark类去测试LockBitmap的性能。

1 public class Benchmark

2 {

3 private static DateTime startDate = DateTime.MinValue;

4 private static DateTime endDate = DateTime.MinValue;

5

6 public static TimeSpan Span { get { return endDate.Subtract(startDate); } }

7

8 public static void Start() { startDate = DateTime.Now; }

9

10 public static void End() { endDate = DateTime.Now; }

11

12 public static double GetSeconds()

13 {

14 if (endDate == DateTime.MinValue) return 0.0;

15 else return Span.TotalSeconds;

16 }

17 }

使用方法

  现在,我们可以使用LockBitmap类非常快地去操作bitmap。

1 public void ChangeColor()

2 {

3 Bitmap bmp = (Bitmap)Image.FromFile(d:\source.png);

4 Benchmark.Start();

相关文章
|
2月前
|
存储 监控
Bitmap
【10月更文挑战第7天】
35 1
|
6月前
|
存储 算法 Java
BitMap介绍
BitMap介绍
35 0
|
6月前
|
API Android开发
55. 【Android教程】位图:Bitmap
55. 【Android教程】位图:Bitmap
77 0
|
存储 缓存 监控
内存优化 | Bitmap优化
在内存优化中,优化 Bitmap 占用的内存效果最为明显,在 Android 里面,大部分 OOM,都是 bitmap 占用资源过大导致的,那么问题来了 如何防止 bitmap 占用资源过大导致 OOM?Android 系统何时会发生 OOM?怎样搭建线上线下一体化内存监控体系?Drump 文件过大,我们线上如何查看?线下监控那些工具你会用吗?关于 Native 层的内存泄漏该如何解决?图片监控你做过哪些努力?内存抖动为什么会引起 OOM?内存监控里面采集方式有哪些? 看完本文,希望可以以本文为索引,然后依次排雷解决上述问题,这样你也是这个领域的专家了
490 0
内存优化 | Bitmap优化
Bitmap高效加载
我们在编程中,如果要插入一张图片,大部分直接使用ImageView直接加载,但在实际编程当中,有时候图片的原始尺寸并不符合ImageView。 使用BitmapFactory类中的四个方法:decodeFile,decodeResource,decodeStream,decodeByteArray(文件,资源,IO流,字节数组)中加载Bitmap对象,可以使用InSampleSize采样率来缩小图片,还可以缩小图片内存大小,一定程度避免OOM。
131 0
|
存储 编解码 Android开发
【Android 内存优化】Bitmap 内存占用计算 ( Bitmap 图片内存占用分析 | Bitmap 内存占用计算 | Bitmap 不同像素密度间的转换 )
【Android 内存优化】Bitmap 内存占用计算 ( Bitmap 图片内存占用分析 | Bitmap 内存占用计算 | Bitmap 不同像素密度间的转换 )
238 0
使用Bitmap.createBitmap遇到的问题
使用Bitmap.createBitmap遇到的问题
463 0
|
Java Android开发
Bitmap详解
Bitmap的分析与使用 Bitmap的创建 创建Bitmap的时候,Java不提供new Bitmap()的形式去创建,而是通过BitmapFactory中的静态方法去创建,如:BitmapFactory.
2107 0