ImageBlur.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*************************************************
  2. Copyright: Copyright QIUJUER 2013.
  3. Author: Qiujuer
  4. Date: 2014-04-18
  5. Description:实现图片模糊处理
  6. **************************************************/
  7. #include<malloc.h>
  8. #define ABS(a) ((a)<(0)?(-a):(a))
  9. #define MAX(a,b) ((a)>(b)?(a):(b))
  10. #define MIN(a,b) ((a)<(b)?(a):(b))
  11. /*************************************************
  12. Function: StackBlur(堆栈模糊)
  13. Description: 使用堆栈方式进行图片像素模糊处理
  14. Calls: malloc
  15. Table Accessed: NULL
  16. Table Updated: NULL
  17. Input: 像素点集合,图片宽,图片高,模糊半径
  18. Output: 返回模糊后的像素点集合
  19. Return: 返回模糊后的像素点集合
  20. Others: NULL
  21. *************************************************/
  22. static int* StackBlur(int* pix, int w, int h, int radius) {
  23. int wm = w - 1;
  24. int hm = h - 1;
  25. int wh = w * h;
  26. int div = radius + radius + 1;
  27. int *r = (int *)malloc(wh * sizeof(int));
  28. int *g = (int *)malloc(wh * sizeof(int));
  29. int *b = (int *)malloc(wh * sizeof(int));
  30. int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
  31. int *vmin = (int *)malloc(MAX(w,h) * sizeof(int));
  32. int divsum = (div + 1) >> 1;
  33. divsum *= divsum;
  34. int *dv = (int *)malloc(256 * divsum * sizeof(int));
  35. for (i = 0; i < 256 * divsum; i++) {
  36. dv[i] = (i / divsum);
  37. }
  38. yw = yi = 0;
  39. int(*stack)[3] = (int(*)[3])malloc(div * 3 * sizeof(int));
  40. int stackpointer;
  41. int stackstart;
  42. int *sir;
  43. int rbs;
  44. int r1 = radius + 1;
  45. int routsum, goutsum, boutsum;
  46. int rinsum, ginsum, binsum;
  47. for (y = 0; y < h; y++) {
  48. rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
  49. for (i = -radius; i <= radius; i++) {
  50. p = pix[yi + (MIN(wm, MAX(i, 0)))];
  51. sir = stack[i + radius];
  52. sir[0] = (p & 0xff0000) >> 16;
  53. sir[1] = (p & 0x00ff00) >> 8;
  54. sir[2] = (p & 0x0000ff);
  55. rbs = r1 - ABS(i);
  56. rsum += sir[0] * rbs;
  57. gsum += sir[1] * rbs;
  58. bsum += sir[2] * rbs;
  59. if (i > 0) {
  60. rinsum += sir[0];
  61. ginsum += sir[1];
  62. binsum += sir[2];
  63. }
  64. else {
  65. routsum += sir[0];
  66. goutsum += sir[1];
  67. boutsum += sir[2];
  68. }
  69. }
  70. stackpointer = radius;
  71. for (x = 0; x < w; x++) {
  72. r[yi] = dv[rsum];
  73. g[yi] = dv[gsum];
  74. b[yi] = dv[bsum];
  75. rsum -= routsum;
  76. gsum -= goutsum;
  77. bsum -= boutsum;
  78. stackstart = stackpointer - radius + div;
  79. sir = stack[stackstart % div];
  80. routsum -= sir[0];
  81. goutsum -= sir[1];
  82. boutsum -= sir[2];
  83. if (y == 0) {
  84. vmin[x] = MIN(x + radius + 1, wm);
  85. }
  86. p = pix[yw + vmin[x]];
  87. sir[0] = (p & 0xff0000) >> 16;
  88. sir[1] = (p & 0x00ff00) >> 8;
  89. sir[2] = (p & 0x0000ff);
  90. rinsum += sir[0];
  91. ginsum += sir[1];
  92. binsum += sir[2];
  93. rsum += rinsum;
  94. gsum += ginsum;
  95. bsum += binsum;
  96. stackpointer = (stackpointer + 1) % div;
  97. sir = stack[(stackpointer) % div];
  98. routsum += sir[0];
  99. goutsum += sir[1];
  100. boutsum += sir[2];
  101. rinsum -= sir[0];
  102. ginsum -= sir[1];
  103. binsum -= sir[2];
  104. yi++;
  105. }
  106. yw += w;
  107. }
  108. for (x = 0; x < w; x++) {
  109. rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
  110. yp = -radius * w;
  111. for (i = -radius; i <= radius; i++) {
  112. yi = MAX(0, yp) + x;
  113. sir = stack[i + radius];
  114. sir[0] = r[yi];
  115. sir[1] = g[yi];
  116. sir[2] = b[yi];
  117. rbs = r1 - ABS(i);
  118. rsum += r[yi] * rbs;
  119. gsum += g[yi] * rbs;
  120. bsum += b[yi] * rbs;
  121. if (i > 0) {
  122. rinsum += sir[0];
  123. ginsum += sir[1];
  124. binsum += sir[2];
  125. }
  126. else {
  127. routsum += sir[0];
  128. goutsum += sir[1];
  129. boutsum += sir[2];
  130. }
  131. if (i < hm) {
  132. yp += w;
  133. }
  134. }
  135. yi = x;
  136. stackpointer = radius;
  137. for (y = 0; y < h; y++) {
  138. // Preserve alpha channel: ( 0xff000000 & pix[yi] )
  139. pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
  140. rsum -= routsum;
  141. gsum -= goutsum;
  142. bsum -= boutsum;
  143. stackstart = stackpointer - radius + div;
  144. sir = stack[stackstart % div];
  145. routsum -= sir[0];
  146. goutsum -= sir[1];
  147. boutsum -= sir[2];
  148. if (x == 0) {
  149. vmin[y] = MIN(y + r1, hm) * w;
  150. }
  151. p = x + vmin[y];
  152. sir[0] = r[p];
  153. sir[1] = g[p];
  154. sir[2] = b[p];
  155. rinsum += sir[0];
  156. ginsum += sir[1];
  157. binsum += sir[2];
  158. rsum += rinsum;
  159. gsum += ginsum;
  160. bsum += binsum;
  161. stackpointer = (stackpointer + 1) % div;
  162. sir = stack[stackpointer];
  163. routsum += sir[0];
  164. goutsum += sir[1];
  165. boutsum += sir[2];
  166. rinsum -= sir[0];
  167. ginsum -= sir[1];
  168. binsum -= sir[2];
  169. yi += w;
  170. }
  171. }
  172. free(r);
  173. free(g);
  174. free(b);
  175. free(vmin);
  176. free(dv);
  177. free(stack);
  178. return(pix);
  179. }