Android图像处理整理

参考:http://blog.csdn.net/luzhenyuxfcy/article/details/49427781
我们常用的处理方式基本都是在对像素矩阵按照一定的数学规律处理得到的,常用的如下;我们也可以通过一个开源的图片处理库(C++)的方式处理,OpenCV,官网:http://opencv.org/   下载对应平台的SDK,这个库很强大,里面基本包含了常用的处理操作,而且效率很高。对应的文字处理库是OCR(顺带提一下)。

以下是参考文献:

点击打开链接

点击打开链接

点击打开链接

这里有一个开源库很是不错:https://github.com/CyberAgent/android-gpuimage

以上是参考链接,已经很详细了,接下来我会出一个通用的demo在后期会更新上传到这篇博客上。

1、圆角图片

[java] view plaincopy
  1. /**
  2. * 转换成圆角
  3. *
  4. * @param bmp
  5. * @param roundPx
  6. * @return
  7. */
  8. public static Bitmap convertToRoundedCorner(Bitmap bmp, float roundPx) {
  9. Bitmap newBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(),
  10. Config.ARGB_8888);
  11. // 得到画布
  12. Canvas canvas = new Canvas(newBmp);
  13. final int color = 0xff424242;
  14. final Paint paint = new Paint();
  15. final Rect rect = new Rect(0, 0, bmp.getWidth(), bmp.getHeight());
  16. final RectF rectF = new RectF(rect);
  17. paint.setAntiAlias(true);
  18. canvas.drawARGB(0, 0, 0, 0);
  19. paint.setColor(color);
  20. // 第二个和第三个参数一样则画的是正圆的一角,否则是椭圆的一角
  21. canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
  22. paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
  23. canvas.drawBitmap(bmp, rect, rect, paint);
  24. return newBmp;
  25. }

2、图片灰度化

[java] view plaincopy
  1. /**
  2. * 图片灰度化处理
  3. *
  4. * @param bmSrc
  5. * */
  6. public Bitmap bitmap2Gray(Bitmap bmSrc) {
  7. // 得到图片的长和宽
  8. int width = bmSrc.getWidth();
  9. int height = bmSrc.getHeight();
  10. // 创建目标灰度图像
  11. Bitmap bmpGray = null;
  12. bmpGray = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  13. // 创建画布
  14. Canvas c = new Canvas(bmpGray);
  15. Paint paint = new Paint();
  16. ColorMatrix cm = new ColorMatrix();
  17. cm.setSaturation(0);
  18. ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
  19. paint.setColorFilter(f);
  20. c.drawBitmap(bmSrc, 0, 0, paint);
  21. return bmpGray;
  22. }

3、线性灰度化

[java] view plaincopy
  1. /**
  2. * 图片线性灰度处理
  3. *
  4. * @param image
  5. * */
  6. public Bitmap lineGrey(Bitmap image) {
  7. // 得到图像的宽度和长度
  8. int width = image.getWidth();
  9. int height = image.getHeight();
  10. // 创建线性拉升灰度图像
  11. Bitmap linegray = null;
  12. linegray = image.copy(Config.ARGB_8888, true);
  13. // 依次循环对图像的像素进行处理
  14. for (int i = 0; i < width; i++) {
  15. for (int j = 0; j < height; j++) {
  16. // 得到每点的像素值
  17. int col = image.getPixel(i, j);
  18. int alpha = col & 0xFF000000;
  19. int red = (col & 0x00FF0000) >> 16;
  20. int green = (col & 0x0000FF00) >> 8;
  21. int blue = (col & 0x000000FF);
  22. // 增加了图像的亮度
  23. red = (int) (1.1 * red + 30);
  24. green = (int) (1.1 * green + 30);
  25. blue = (int) (1.1 * blue + 30);
  26. // 对图像像素越界进行处理
  27. if (red >= 255) {
  28. red = 255;
  29. }
  30. if (green >= 255) {
  31. green = 255;
  32. }
  33. if (blue >= 255) {
  34. blue = 255;
  35. }
  36. // 新的ARGB
  37. int newColor = alpha | (red << 16) | (green << 8) | blue;
  38. // 设置新图像的RGB值
  39. linegray.setPixel(i, j, newColor);
  40. }
  41. }
  42. return linegray;
  43. }

4、图片二值化

[java] view plaincopy
  1. /**
  2. * 图像二值化处理
  3. *
  4. * @param graymap
  5. * */
  6. public Bitmap gray2Binary(Bitmap graymap) {
  7. // 得到图形的宽度和长度
  8. int width = graymap.getWidth();
  9. int height = graymap.getHeight();
  10. // 创建二值化图像
  11. Bitmap binarymap = null;
  12. binarymap = graymap.copy(Config.ARGB_8888, true);
  13. // 依次循环,对图像的像素进行处理
  14. for (int i = 0; i < width; i++) {
  15. for (int j = 0; j < height; j++) {
  16. // 得到当前像素的值
  17. int col = binarymap.getPixel(i, j);
  18. // 得到alpha通道的值
  19. int alpha = col & 0xFF000000;
  20. // 得到图像的像素RGB的值
  21. int red = (col & 0x00FF0000) >> 16;
  22. int green = (col & 0x0000FF00) >> 8;
  23. int blue = (col & 0x000000FF);
  24. // 用公式X = 0.3×R+0.59×G+0.11×B计算出X代替原来的RGB
  25. int gray = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
  26. // 对图像进行二值化处理
  27. if (gray <= 95) {
  28. gray = 0;
  29. } else {
  30. gray = 255;
  31. }
  32. // 新的ARGB
  33. int newColor = alpha | (gray << 16) | (gray << 8) | gray;
  34. // 设置新图像的当前像素值
  35. binarymap.setPixel(i, j, newColor);
  36. }
  37. }
  38. return binarymap;
  39. }

5、高斯模糊

[java] view plaincopy
  1. /**
  2. * 高斯模糊
  3. *
  4. * @param bmp
  5. * @return
  6. */
  7. public static Bitmap convertToBlur(Bitmap bmp) {
  8. // 高斯矩阵
  9. int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
  10. int width = bmp.getWidth();
  11. int height = bmp.getHeight();
  12. Bitmap newBmp = Bitmap.createBitmap(width, height,
  13. Bitmap.Config.RGB_565);
  14. int pixR = 0;
  15. int pixG = 0;
  16. int pixB = 0;
  17. int pixColor = 0;
  18. int newR = 0;
  19. int newG = 0;
  20. int newB = 0;
  21. int delta = 16; // 值越小图片会越亮,越大则越暗
  22. int idx = 0;
  23. int[] pixels = new int[width * height];
  24. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  25. for (int i = 1, length = height - 1; i < length; i++) {
  26. for (int k = 1, len = width - 1; k < len; k++) {
  27. idx = 0;
  28. for (int m = -1; m <= 1; m++) {
  29. for (int n = -1; n <= 1; n++) {
  30. pixColor = pixels[(i + m) * width + k + n];
  31. pixR = Color.red(pixColor);
  32. pixG = Color.green(pixColor);
  33. pixB = Color.blue(pixColor);
  34. newR = newR + pixR * gauss[idx];
  35. newG = newG + pixG * gauss[idx];
  36. newB = newB + pixB * gauss[idx];
  37. idx++;
  38. }
  39. }
  40. newR /= delta;
  41. newG /= delta;
  42. newB /= delta;
  43. newR = Math.min(255, Math.max(0, newR));
  44. newG = Math.min(255, Math.max(0, newG));
  45. newB = Math.min(255, Math.max(0, newB));
  46. pixels[i * width + k] = Color.argb(255, newR, newG, newB);
  47. newR = 0;
  48. newG = 0;
  49. newB = 0;
  50. }
  51. }
  52. newBmp.setPixels(pixels, 0, width, 0, 0, width, height);
  53. return newBmp;
  54. }

6、素描效果

[java] view plaincopy
  1. /**
  2. * 素描效果
  3. *
  4. * @param bmp
  5. * @return
  6. */
  7. public static Bitmap convertToSketch(Bitmap bmp) {
  8. int pos, row, col, clr;
  9. int width = bmp.getWidth();
  10. int height = bmp.getHeight();
  11. int[] pixSrc = new int[width * height];
  12. int[] pixNvt = new int[width * height];
  13. // 先对图象的像素处理成灰度颜色后再取反
  14. bmp.getPixels(pixSrc, 0, width, 0, 0, width, height);
  15. for (row = 0; row < height; row++) {
  16. for (col = 0; col < width; col++) {
  17. pos = row * width + col;
  18. pixSrc[pos] = (Color.red(pixSrc[pos])
  19. + Color.green(pixSrc[pos]) + Color.blue(pixSrc[pos])) / 3;
  20. pixNvt[pos] = 255 - pixSrc[pos];
  21. }
  22. }
  23. // 对取反的像素进行高斯模糊, 强度可以设置,暂定为5.0
  24. gaussGray(pixNvt, 5.0, 5.0, width, height);
  25. // 灰度颜色和模糊后像素进行差值运算
  26. for (row = 0; row < height; row++) {
  27. for (col = 0; col < width; col++) {
  28. pos = row * width + col;
  29. clr = pixSrc[pos] << 8;
  30. clr /= 256 - pixNvt[pos];
  31. clr = Math.min(clr, 255);
  32. pixSrc[pos] = Color.rgb(clr, clr, clr);
  33. }
  34. }
  35. bmp.setPixels(pixSrc, 0, width, 0, 0, width, height);
  36. return bmp;
  37. }
  38. private static int gaussGray(int[] psrc, double horz, double vert,
  39. int width, int height) {
  40. int[] dst, src;
  41. double[] n_p, n_m, d_p, d_m, bd_p, bd_m;
  42. double[] val_p, val_m;
  43. int i, j, t, k, row, col, terms;
  44. int[] initial_p, initial_m;
  45. double std_dev;
  46. int row_stride = width;
  47. int max_len = Math.max(width, height);
  48. int sp_p_idx, sp_m_idx, vp_idx, vm_idx;
  49. val_p = new double[max_len];
  50. val_m = new double[max_len];
  51. n_p = new double[5];
  52. n_m = new double[5];
  53. d_p = new double[5];
  54. d_m = new double[5];
  55. bd_p = new double[5];
  56. bd_m = new double[5];
  57. src = new int[max_len];
  58. dst = new int[max_len];
  59. initial_p = new int[4];
  60. initial_m = new int[4];
  61. // 垂直方向
  62. if (vert > 0.0) {
  63. vert = Math.abs(vert) + 1.0;
  64. std_dev = Math.sqrt(-(vert * vert) / (2 * Math.log(1.0 / 255.0)));
  65. // 初试化常量
  66. findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
  67. for (col = 0; col < width; col++) {
  68. for (k = 0; k < max_len; k++) {
  69. val_m[k] = val_p[k] = 0;
  70. }
  71. for (t = 0; t < height; t++) {
  72. src[t] = psrc[t * row_stride + col];
  73. }
  74. sp_p_idx = 0;
  75. sp_m_idx = height - 1;
  76. vp_idx = 0;
  77. vm_idx = height - 1;
  78. initial_p[0] = src[0];
  79. initial_m[0] = src[height - 1];
  80. for (row = 0; row < height; row++) {
  81. terms = (row < 4) ? row : 4;
  82. for (i = 0; i <= terms; i++) {
  83. val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i]
  84. * val_p[vp_idx - i];
  85. val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i]
  86. * val_m[vm_idx + i];
  87. }
  88. for (j = i; j <= 4; j++) {
  89. val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];
  90. val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];
  91. }
  92. sp_p_idx++;
  93. sp_m_idx--;
  94. vp_idx++;
  95. vm_idx--;
  96. }
  97. transferGaussPixels(val_p, val_m, dst, 1, height);
  98. for (t = 0; t < height; t++) {
  99. psrc[t * row_stride + col] = dst[t];
  100. }
  101. }
  102. }
  103. // 水平方向
  104. if (horz > 0.0) {
  105. horz = Math.abs(horz) + 1.0;
  106. if (horz != vert) {
  107. std_dev = Math.sqrt(-(horz * horz)
  108. / (2 * Math.log(1.0 / 255.0)));
  109. // 初试化常量
  110. findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
  111. }
  112. for (row = 0; row < height; row++) {
  113. for (k = 0; k < max_len; k++) {
  114. val_m[k] = val_p[k] = 0;
  115. }
  116. for (t = 0; t < width; t++) {
  117. src[t] = psrc[row * row_stride + t];
  118. }
  119. sp_p_idx = 0;
  120. sp_m_idx = width - 1;
  121. vp_idx = 0;
  122. vm_idx = width - 1;
  123. initial_p[0] = src[0];
  124. initial_m[0] = src[width - 1];
  125. for (col = 0; col < width; col++) {
  126. terms = (col < 4) ? col : 4;
  127. for (i = 0; i <= terms; i++) {
  128. val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i]
  129. * val_p[vp_idx - i];
  130. val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i]
  131. * val_m[vm_idx + i];
  132. }
  133. for (j = i; j <= 4; j++) {
  134. val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];
  135. val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];
  136. }
  137. sp_p_idx++;
  138. sp_m_idx--;
  139. vp_idx++;
  140. vm_idx--;
  141. }
  142. transferGaussPixels(val_p, val_m, dst, 1, width);
  143. for (t = 0; t < width; t++) {
  144. psrc[row * row_stride + t] = dst[t];
  145. }
  146. }
  147. }
  148. return 0;
  149. }
  150. private static void transferGaussPixels(double[] src1, double[] src2,
  151. int[] dest, int bytes, int width) {
  152. int i, j, k, b;
  153. int bend = bytes * width;
  154. double sum;
  155. i = j = k = 0;
  156. for (b = 0; b < bend; b++) {
  157. sum = src1[i++] + src2[j++];
  158. if (sum > 255)
  159. sum = 255;
  160. else if (sum < 0)
  161. sum = 0;
  162. dest[k++] = (int) sum;
  163. }
  164. }
  165. private static void findConstants(double[] n_p, double[] n_m, double[] d_p,
  166. double[] d_m, double[] bd_p, double[] bd_m, double std_dev) {
  167. double div = Math.sqrt(2 * 3.141593) * std_dev;
  168. double x0 = -1.783 / std_dev;
  169. double x1 = -1.723 / std_dev;
  170. double x2 = 0.6318 / std_dev;
  171. double x3 = 1.997 / std_dev;
  172. double x4 = 1.6803 / div;
  173. double x5 = 3.735 / div;
  174. double x6 = -0.6803 / div;
  175. double x7 = -0.2598 / div;
  176. int i;
  177. n_p[0] = x4 + x6;
  178. n_p[1] = (Math.exp(x1)
  179. * (x7 * Math.sin(x3) - (x6 + 2 * x4) * Math.cos(x3)) + Math
  180. .exp(x0) * (x5 * Math.sin(x2) - (2 * x6 + x4) * Math.cos(x2)));
  181. n_p[2] = (2
  182. * Math.exp(x0 + x1)
  183. * ((x4 + x6) * Math.cos(x3) * Math.cos(x2) - x5 * Math.cos(x3)
  184. * Math.sin(x2) - x7 * Math.cos(x2) * Math.sin(x3)) + x6
  185. * Math.exp(2 * x0) + x4 * Math.exp(2 * x1));
  186. n_p[3] = (Math.exp(x1 + 2 * x0)
  187. * (x7 * Math.sin(x3) - x6 * Math.cos(x3)) + Math.exp(x0 + 2
  188. * x1)
  189. * (x5 * Math.sin(x2) - x4 * Math.cos(x2)));
  190. n_p[4] = 0.0;
  191. d_p[0] = 0.0;
  192. d_p[1] = -2 * Math.exp(x1) * Math.cos(x3) - 2 * Math.exp(x0)
  193. * Math.cos(x2);
  194. d_p[2] = 4 * Math.cos(x3) * Math.cos(x2) * Math.exp(x0 + x1)
  195. + Math.exp(2 * x1) + Math.exp(2 * x0);
  196. d_p[3] = -2 * Math.cos(x2) * Math.exp(x0 + 2 * x1) - 2 * Math.cos(x3)
  197. * Math.exp(x1 + 2 * x0);
  198. d_p[4] = Math.exp(2 * x0 + 2 * x1);
  199. for (i = 0; i <= 4; i++) {
  200. d_m[i] = d_p[i];
  201. }
  202. n_m[0] = 0.0;
  203. for (i = 1; i <= 4; i++) {
  204. n_m[i] = n_p[i] - d_p[i] * n_p[0];
  205. }
  206. double sum_n_p, sum_n_m, sum_d;
  207. double a, b;
  208. sum_n_p = 0.0;
  209. sum_n_m = 0.0;
  210. sum_d = 0.0;
  211. for (i = 0; i <= 4; i++) {
  212. sum_n_p += n_p[i];
  213. sum_n_m += n_m[i];
  214. sum_d += d_p[i];
  215. }
  216. a = sum_n_p / (1.0 + sum_d);
  217. b = sum_n_m / (1.0 + sum_d);
  218. for (i = 0; i <= 4; i++) {
  219. bd_p[i] = d_p[i] * a;
  220. bd_m[i] = d_m[i] * b;
  221. }
  222. }

7、锐化

[java] view plaincopy
  1. /**
  2. * 图片锐化(拉普拉斯变换)
  3. *
  4. * @param bmp
  5. * @return
  6. */
  7. public static Bitmap sharpenImageAmeliorate(Bitmap bmp) {
  8. // 拉普拉斯矩阵
  9. int[] laplacian = new int[] { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
  10. int width = bmp.getWidth();
  11. int height = bmp.getHeight();
  12. Bitmap bitmap = Bitmap.createBitmap(width, height,
  13. Bitmap.Config.RGB_565);
  14. int pixR = 0;
  15. int pixG = 0;
  16. int pixB = 0;
  17. int pixColor = 0;
  18. int newR = 0;
  19. int newG = 0;
  20. int newB = 0;
  21. int idx = 0;
  22. float alpha = 0.3F;
  23. int[] pixels = new int[width * height];
  24. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  25. for (int i = 1, length = height - 1; i < length; i++) {
  26. for (int k = 1, len = width - 1; k < len; k++) {
  27. idx = 0;
  28. for (int m = -1; m <= 1; m++) {
  29. for (int n = -1; n <= 1; n++) {
  30. pixColor = pixels[(i + n) * width + k + m];
  31. pixR = Color.red(pixColor);
  32. pixG = Color.green(pixColor);
  33. pixB = Color.blue(pixColor);
  34. newR = newR + (int) (pixR * laplacian[idx] * alpha);
  35. newG = newG + (int) (pixG * laplacian[idx] * alpha);
  36. newB = newB + (int) (pixB * laplacian[idx] * alpha);
  37. idx++;
  38. }
  39. }
  40. newR = Math.min(255, Math.max(0, newR));
  41. newG = Math.min(255, Math.max(0, newG));
  42. newB = Math.min(255, Math.max(0, newB));
  43. pixels[i * width + k] = Color.argb(255, newR, newG, newB);
  44. newR = 0;
  45. newG = 0;
  46. newB = 0;
  47. }
  48. }
  49. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  50. return bitmap;
  51. }

8、怀旧

[java] view plaincopy
  1. private Bitmap OldRemeberImage(Bitmap bmp)
  2. {
  3. /*
  4. * 怀旧处理算法即设置新的RGB
  5. * R=0.393r+0.769g+0.189b
  6. * G=0.349r+0.686g+0.168b
  7. * B=0.272r+0.534g+0.131b
  8. */
  9. int width = bmp.getWidth();
  10. int height = bmp.getHeight();
  11. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  12. int pixColor = 0;
  13. int pixR = 0;
  14. int pixG = 0;
  15. int pixB = 0;
  16. int newR = 0;
  17. int newG = 0;
  18. int newB = 0;
  19. int[] pixels = new int[width * height];
  20. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  21. for (int i = 0; i < height; i++)
  22. {
  23. for (int k = 0; k < width; k++)
  24. {
  25. pixColor = pixels[width * i + k];
  26. pixR = Color.red(pixColor);
  27. pixG = Color.green(pixColor);
  28. pixB = Color.blue(pixColor);
  29. newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
  30. newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
  31. newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
  32. int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
  33. pixels[width * i + k] = newColor;
  34. }
  35. }
  36. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  37. return bitmap;
  38. }

9、浮雕

[java] view plaincopy
  1. //图片浮雕处理
  2. //底片效果也非常简单:将当前像素点的RGB值分别与255之差后的值作为当前点的RGB
  3. //灰度图像:通常使用的方法是gray=0.3*pixR+0.59*pixG+0.11*pixB
  4. private Bitmap ReliefImage(Bitmap bmp)
  5. {
  6. /*
  7. * 算法原理:(前一个像素点RGB-当前像素点RGB+127)作为当前像素点RGB值
  8. * 在ABC中计算B点浮雕效果(RGB值在0~255)
  9. * B.r = C.r - B.r + 127
  10. * B.g = C.g - B.g + 127
  11. * B.b = C.b - B.b + 127
  12. */
  13. int width = bmp.getWidth();
  14. int height = bmp.getHeight();
  15. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  16. int pixColor = 0;
  17. int pixR = 0;
  18. int pixG = 0;
  19. int pixB = 0;
  20. int newR = 0;
  21. int newG = 0;
  22. int newB = 0;
  23. int[] pixels = new int[width * height];
  24. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  25. for (int i = 1; i < height-1; i++)
  26. {
  27. for (int k = 1; k < width-1; k++)
  28. {
  29. //获取前一个像素颜色
  30. pixColor = pixels[width * i + k];
  31. pixR = Color.red(pixColor);
  32. pixG = Color.green(pixColor);
  33. pixB = Color.blue(pixColor);
  34. //获取当前像素
  35. pixColor = pixels[(width * i + k) + 1];
  36. newR = Color.red(pixColor) - pixR +127;
  37. newG = Color.green(pixColor) - pixG +127;
  38. newB = Color.blue(pixColor) - pixB +127;
  39. newR = Math.min(255, Math.max(0, newR));
  40. newG = Math.min(255, Math.max(0, newG));
  41. newB = Math.min(255, Math.max(0, newB));
  42. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  43. }
  44. }
  45. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  46. return bitmap;
  47. }

10、光照效果

[java] view plaincopy
  1. //图片光照效果
  2. private Bitmap SunshineImage(Bitmap bmp)
  3. {
  4. /*
  5. * 算法原理:(前一个像素点RGB-当前像素点RGB+127)作为当前像素点RGB值
  6. * 在ABC中计算B点浮雕效果(RGB值在0~255)
  7. * B.r = C.r - B.r + 127
  8. * B.g = C.g - B.g + 127
  9. * B.b = C.b - B.b + 127
  10. * 光照中心取长宽较小值为半径,也可以自定义从左上角射过来
  11. */
  12. int width = bmp.getWidth();
  13. int height = bmp.getHeight();
  14. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  15. int pixColor = 0;
  16. int pixR = 0;
  17. int pixG = 0;
  18. int pixB = 0;
  19. int newR = 0;
  20. int newG = 0;
  21. int newB = 0;
  22. //围绕圆形光照
  23. int centerX = width / 2;
  24. int centerY = height / 2;
  25. int radius = Math.min(centerX, centerY);
  26. float strength = 150F;  //光照强度100-150
  27. int[] pixels = new int[width * height];
  28. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  29. for (int i = 1; i < height-1; i++)
  30. {
  31. for (int k = 1; k < width-1; k++)
  32. {
  33. //获取前一个像素颜色
  34. pixColor = pixels[width * i + k];
  35. pixR = Color.red(pixColor);
  36. pixG = Color.green(pixColor);
  37. pixB = Color.blue(pixColor);
  38. newR = pixR;
  39. newG = pixG;
  40. newB = pixB;
  41. //计算当前点到光照中心的距离,平面坐标系中两点之间的距离
  42. int distance = (int) (Math.pow((centerY-i), 2) + Math.pow((centerX-k), 2));
  43. if(distance < radius*radius)
  44. {
  45. //按照距离大小计算增强的光照值
  46. int result = (int)(strength*( 1.0-Math.sqrt(distance) / radius ));
  47. newR = pixR + result;
  48. newG = newG + result;
  49. newB = pixB + result;
  50. }
  51. newR = Math.min(255, Math.max(0, newR));
  52. newG = Math.min(255, Math.max(0, newG));
  53. newB = Math.min(255, Math.max(0, newB));
  54. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  55. }
  56. }
  57. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  58. return bitmap;
  59. }

11、冰冻效果

[java] view plaincopy
  1. //图片冰冻效果
  2. private Bitmap IceImage(Bitmap bmp)
  3. {
  4. int width = bmp.getWidth();
  5. int height = bmp.getHeight();
  6. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  7. int pixColor = 0;
  8. int pixR = 0;
  9. int pixG = 0;
  10. int pixB = 0;
  11. int newColor = 0;
  12. int newR = 0;
  13. int newG = 0;
  14. int newB =0;
  15. int[] pixels = new int[width * height];
  16. bmp.getPixels(pixels, 0, width, 0, 0, width, height);
  17. for (int i = 0; i < height; i++)
  18. {
  19. for (int k = 0; k < width; k++)
  20. {
  21. //获取前一个像素颜色
  22. pixColor = pixels[width * i + k];
  23. pixR = Color.red(pixColor);
  24. pixG = Color.green(pixColor);
  25. pixB = Color.blue(pixColor);
  26. //红色
  27. newColor = pixR - pixG - pixB;
  28. newColor = newColor * 3 / 2;
  29. if(newColor < 0) {
  30. newColor = -newColor;
  31. }
  32. if(newColor >255) {
  33. newColor = 255;
  34. }
  35. newR = newColor;
  36. //绿色
  37. newColor = pixG - pixB - pixR;
  38. newColor = newColor * 3 / 2;
  39. if(newColor < 0) {
  40. newColor = -newColor;
  41. }
  42. if(newColor >255) {
  43. newColor = 255;
  44. }
  45. newG = newColor;
  46. //蓝色
  47. newColor = pixB - pixG - pixR;
  48. newColor = newColor * 3 / 2;
  49. if(newColor < 0) {
  50. newColor = -newColor;
  51. }
  52. if(newColor >255) {
  53. newColor = 255;
  54. }
  55. newB = newColor;
  56. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  57. }
  58. }
  59. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  60. return bitmap;
  61. }

12、直方图均值化

[java] view plaincopy
  1. /*
  2. *直方图均衡化
  3. */
  4. public Bitmap histEqualize(Bitmap myBitmap){
  5. // Create new array
  6. int width = myBitmap.getWidth();
  7. int height = myBitmap.getHeight();
  8. int[] pix = new int[width * height];
  9. myBitmap.getPixels(pix, 0, width, 0, 0, width, height);
  10. Matrix dataR=getDataR(pix, width, height);
  11. Matrix dataG=getDataG(pix, width, height);
  12. Matrix dataB=getDataB(pix, width, height);
  13. //Matrix dataGray=getDataGray(pix, width, height);
  14. /
  15. dataR=eachEqualize(dataR,width,height);
  16. dataG=eachEqualize(dataG,width,height);
  17. dataB=eachEqualize(dataB,width,height);
  18. ///
  19. // Change bitmap to use new array
  20. Bitmap bitmap=makeToBitmap(dataR, dataG, dataB, width, height);
  21. myBitmap = null;
  22. pix = null;
  23. return bitmap;
  24. }
  25. private Matrix eachEqualize(Matrix temp,int width,int height){
  26. // 灰度映射表
  27. int bMap[]=new int[256];
  28. // 灰度映射表
  29. int lCount[]=new int[256];
  30. // 重置计数为0
  31. int i,j;
  32. for (i = 0; i < 256; i ++){
  33. // 清零
  34. lCount[i] = 0;
  35. }
  36. // 计算各个灰度值的计数 - 参考灰度直方图的绘制代码 (对话框类中)
  37. for (i = 0; i < height; i ++){
  38. for (j = 0; j < width; j ++){
  39. lCount[(int)temp.get(i, j)]++;  // 计数加1
  40. }
  41. }
  42. // 计算灰度映射表
  43. for (i = 0; i < 256; i++){
  44. // 初始为0
  45. int Temp = 0;
  46. for (j = 0; j <= i ; j++){
  47. Temp += lCount[j];
  48. }
  49. // 计算对应的新灰度值
  50. bMap[i] = (int) (Temp * 255 / height / width);
  51. }
  52. // 每行
  53. for (i = 0; i < height; i++){
  54. // 每列
  55. for (j = 0; j < width; j++){
  56. temp.set(i, j, bMap[(int)temp.get(i,j)]);
  57. }
  58. }
  59. return temp;
  60. }

特效处理代码源码:

[java] view plaincopy
  1. package com.lzy.imageprolib.kits;
  2. import android.graphics.Bitmap;
  3. import android.graphics.Canvas;
  4. import android.graphics.Color;
  5. import android.graphics.ColorMatrix;
  6. import android.graphics.ColorMatrixColorFilter;
  7. import android.graphics.LinearGradient;
  8. import android.graphics.Matrix;
  9. import android.graphics.Paint;
  10. import android.graphics.PixelFormat;
  11. import android.graphics.PorterDuff;
  12. import android.graphics.PorterDuffXfermode;
  13. import android.graphics.Rect;
  14. import android.graphics.RectF;
  15. import android.graphics.Shader;
  16. import android.graphics.drawable.Drawable;
  17. import android.media.ThumbnailUtils;
  18. import android.os.Environment;
  19. import android.text.TextUtils;
  20. import java.io.File;
  21. import java.io.FileOutputStream;
  22. import java.io.IOException;
  23. import java.io.OutputStream;
  24. import java.util.Random;
  25. /**
  26. * Created by luzhenyu on 2016/5/11.
  27. */
  28. public class ImageProcessHelper {
  29. private ImageProcessHelper() {
  30. }
  31. private static class HelperTemp {
  32. private static ImageProcessHelper helper = new ImageProcessHelper();
  33. }
  34. /**
  35. * 获取处理实例
  36. * Get ImageProcessHelper instance by single
  37. *
  38. * @return ImageProcessHelper
  39. */
  40. public static ImageProcessHelper getInstance() {
  41. return HelperTemp.helper;
  42. }
  43. ///
  44. //图片位置//
  45. /**
  46. * 位置 上下左右中 左上角 左下角 右上角 右下角 中间
  47. * */
  48. public enum Position {
  49. LEFT,
  50. RIGHT,
  51. TOP,
  52. BOTTOM,
  53. CENTRE,
  54. LEFT_UP,
  55. LEFT_DOWN,
  56. RIGHT_UP,
  57. RIGHT_DOWN,
  58. CENTER;
  59. }
  60. /**
  61. * 图片格式
  62. * */
  63. public enum Format {
  64. JPEG,
  65. PNG,
  66. WEBP;
  67. }
  68. /**
  69. * Bitmap图片转换成圆角
  70. *
  71. * @param mBitmapSrc 图片源
  72. * @param roundPx    float
  73. * @return Bitmap
  74. */
  75. public Bitmap convert2RoundedCorner(Bitmap mBitmapSrc, float roundPx) {
  76. Bitmap newBitmap = Bitmap.createBitmap(mBitmapSrc.getWidth(), mBitmapSrc.getHeight(),
  77. Bitmap.Config.ARGB_8888);
  78. // 得到画布
  79. Canvas canvas = new Canvas(newBitmap);
  80. final int color = 0xff424242;
  81. final Paint paint = new Paint();
  82. final Rect rect = new Rect(0, 0, mBitmapSrc.getWidth(), mBitmapSrc.getHeight());
  83. final RectF rectF = new RectF(rect);
  84. paint.setAntiAlias(true);
  85. canvas.drawARGB(0, 0, 0, 0);
  86. paint.setColor(color);
  87. // 第二个和第三个参数一样则画的是正圆的一角,否则是椭圆的一角
  88. canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
  89. paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  90. canvas.drawBitmap(mBitmapSrc, rect, rect, paint);
  91. return newBitmap;
  92. }
  93. /**
  94. * Bitmap图片灰度化处理
  95. *
  96. * @param mBitmapSrc 图片源
  97. * @return Bitmap
  98. */
  99. public Bitmap bitmap2Gray(Bitmap mBitmapSrc) {
  100. // 得到图片的长和宽
  101. int width = mBitmapSrc.getWidth();
  102. int height = mBitmapSrc.getHeight();
  103. // 创建目标灰度图像
  104. Bitmap bmpGray = null;
  105. bmpGray = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  106. // 创建画布
  107. Canvas c = new Canvas(bmpGray);
  108. Paint paint = new Paint();
  109. ColorMatrix cm = new ColorMatrix();
  110. cm.setSaturation(0);
  111. ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
  112. paint.setColorFilter(f);
  113. c.drawBitmap(mBitmapSrc, 0, 0, paint);
  114. return bmpGray;
  115. }
  116. /**
  117. * 图片线性灰度处理
  118. *
  119. * @param mBitmapSrc 图片源
  120. * @return Bitmap
  121. */
  122. public Bitmap bitmap2LineGrey(Bitmap mBitmapSrc) {
  123. // 得到图像的宽度和长度
  124. int width = mBitmapSrc.getWidth();
  125. int height = mBitmapSrc.getHeight();
  126. // 创建线性拉升灰度图像
  127. Bitmap bitmap = mBitmapSrc.copy(Bitmap.Config.ARGB_8888, true);
  128. // 依次循环对图像的像素进行处理
  129. for (int i = 0; i < width; i++) {
  130. for (int j = 0; j < height; j++) {
  131. // 得到每点的像素值
  132. int col = mBitmapSrc.getPixel(i, j);
  133. int alpha = col & 0xFF000000;
  134. int red = (col & 0x00FF0000) >> 16;
  135. int green = (col & 0x0000FF00) >> 8;
  136. int blue = (col & 0x000000FF);
  137. // 增加了图像的亮度
  138. red = (int) (1.1 * red + 30);
  139. green = (int) (1.1 * green + 30);
  140. blue = (int) (1.1 * blue + 30);
  141. // 对图像像素越界进行处理
  142. if (red >= 255) {
  143. red = 255;
  144. }
  145. if (green >= 255) {
  146. green = 255;
  147. }
  148. if (blue >= 255) {
  149. blue = 255;
  150. }
  151. // 新的ARGB
  152. int newColor = alpha | (red << 16) | (green << 8) | blue;
  153. // 设置新图像的RGB值
  154. bitmap.setPixel(i, j, newColor);
  155. }
  156. }
  157. return bitmap;
  158. }
  159. /**
  160. * 图像二值化处理
  161. *
  162. * @param mBitmapSrc 图片源
  163. * @return Bitmap
  164. */
  165. public Bitmap gray2Binary(Bitmap mBitmapSrc) {
  166. // 得到图形的宽度和长度
  167. int width = mBitmapSrc.getWidth();
  168. int height = mBitmapSrc.getHeight();
  169. // 创建二值化图像
  170. Bitmap binarybm = null;
  171. binarybm = mBitmapSrc.copy(Bitmap.Config.ARGB_8888, true);
  172. // 依次循环,对图像的像素进行处理
  173. for (int i = 0; i < width; i++) {
  174. for (int j = 0; j < height; j++) {
  175. // 得到当前像素的值
  176. int col = binarybm.getPixel(i, j);
  177. // 得到alpha通道的值
  178. int alpha = col & 0xFF000000;
  179. // 得到图像的像素RGB的值
  180. int red = (col & 0x00FF0000) >> 16;
  181. int green = (col & 0x0000FF00) >> 8;
  182. int blue = (col & 0x000000FF);
  183. // 用公式X = 0.3×R+0.59×G+0.11×B计算出X代替原来的RGB
  184. int gray = (int) ((float) red * 0.3 + (float) green * 0.59 + (float) blue * 0.11);
  185. // 对图像进行二值化处理
  186. if (gray <= 95) {
  187. gray = 0;
  188. } else {
  189. gray = 255;
  190. }
  191. // 新的ARGB
  192. int newColor = alpha | (gray << 16) | (gray << 8) | gray;
  193. // 设置新图像的当前像素值
  194. binarybm.setPixel(i, j, newColor);
  195. }
  196. }
  197. return binarybm;
  198. }
  199. /**
  200. * 高斯模糊
  201. *
  202. * @param mBitmapSrc 图片源
  203. * @return Bitmap
  204. */
  205. public Bitmap convertToBlur(Bitmap mBitmapSrc) {
  206. // 高斯矩阵
  207. int[] gauss = new int[]{1, 2, 1, 2, 4, 2, 1, 2, 1};
  208. int width = mBitmapSrc.getWidth();
  209. int height = mBitmapSrc.getHeight();
  210. Bitmap newBmp = Bitmap.createBitmap(width, height,
  211. Bitmap.Config.RGB_565);
  212. int pixR = 0;
  213. int pixG = 0;
  214. int pixB = 0;
  215. int pixColor = 0;
  216. int newR = 0;
  217. int newG = 0;
  218. int newB = 0;
  219. int delta = 16; // 值越小图片会越亮,越大则越暗
  220. int idx = 0;
  221. int[] pixels = new int[width * height];
  222. mBitmapSrc.getPixels(pixels, 0, width, 0, 0, width, height);
  223. for (int i = 1, length = height - 1; i < length; i++) {
  224. for (int k = 1, len = width - 1; k < len; k++) {
  225. idx = 0;
  226. for (int m = -1; m <= 1; m++) {
  227. for (int n = -1; n <= 1; n++) {
  228. pixColor = pixels[(i + m) * width + k + n];
  229. pixR = Color.red(pixColor);
  230. pixG = Color.green(pixColor);
  231. pixB = Color.blue(pixColor);
  232. newR = newR + pixR * gauss[idx];
  233. newG = newG + pixG * gauss[idx];
  234. newB = newB + pixB * gauss[idx];
  235. idx++;
  236. }
  237. }
  238. newR /= delta;
  239. newG /= delta;
  240. newB /= delta;
  241. newR = Math.min(255, Math.max(0, newR));
  242. newG = Math.min(255, Math.max(0, newG));
  243. newB = Math.min(255, Math.max(0, newB));
  244. pixels[i * width + k] = Color.argb(255, newR, newG, newB);
  245. newR = 0;
  246. newG = 0;
  247. newB = 0;
  248. }
  249. }
  250. newBmp.setPixels(pixels, 0, width, 0, 0, width, height);
  251. return newBmp;
  252. }
  253. /**
  254. * 素描效果
  255. *
  256. * @param mBitmapSrc 图片源
  257. * @return Bitmap
  258. */
  259. public Bitmap convertToSketch(Bitmap mBitmapSrc) {
  260. int pos, row, col, clr;
  261. int width = mBitmapSrc.getWidth();
  262. int height = mBitmapSrc.getHeight();
  263. int[] pixSrc = new int[width * height];
  264. int[] pixNvt = new int[width * height];
  265. // 先对图象的像素处理成灰度颜色后再取反
  266. mBitmapSrc.getPixels(pixSrc, 0, width, 0, 0, width, height);
  267. for (row = 0; row < height; row++) {
  268. for (col = 0; col < width; col++) {
  269. pos = row * width + col;
  270. pixSrc[pos] = (Color.red(pixSrc[pos])
  271. + Color.green(pixSrc[pos]) + Color.blue(pixSrc[pos])) / 3;
  272. pixNvt[pos] = 255 - pixSrc[pos];
  273. }
  274. }
  275. // 对取反的像素进行高斯模糊, 强度可以设置,暂定为5.0
  276. gaussGray(pixNvt, 5.0, 5.0, width, height);
  277. // 灰度颜色和模糊后像素进行差值运算
  278. for (row = 0; row < height; row++) {
  279. for (col = 0; col < width; col++) {
  280. pos = row * width + col;
  281. clr = pixSrc[pos] << 8;
  282. clr /= 256 - pixNvt[pos];
  283. clr = Math.min(clr, 255);
  284. pixSrc[pos] = Color.rgb(clr, clr, clr);
  285. }
  286. }
  287. mBitmapSrc.setPixels(pixSrc, 0, width, 0, 0, width, height);
  288. return mBitmapSrc;
  289. }
  290. private int gaussGray(int[] psrc, double horz, double vert,
  291. int width, int height) {
  292. int[] dst, src;
  293. double[] n_p, n_m, d_p, d_m, bd_p, bd_m;
  294. double[] val_p, val_m;
  295. int i, j, t, k, row, col, terms;
  296. int[] initial_p, initial_m;
  297. double std_dev;
  298. int row_stride = width;
  299. int max_len = Math.max(width, height);
  300. int sp_p_idx, sp_m_idx, vp_idx, vm_idx;
  301. val_p = new double[max_len];
  302. val_m = new double[max_len];
  303. n_p = new double[5];
  304. n_m = new double[5];
  305. d_p = new double[5];
  306. d_m = new double[5];
  307. bd_p = new double[5];
  308. bd_m = new double[5];
  309. src = new int[max_len];
  310. dst = new int[max_len];
  311. initial_p = new int[4];
  312. initial_m = new int[4];
  313. // 垂直方向
  314. if (vert > 0.0) {
  315. vert = Math.abs(vert) + 1.0;
  316. std_dev = Math.sqrt(-(vert * vert) / (2 * Math.log(1.0 / 255.0)));
  317. // 初试化常量
  318. findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
  319. for (col = 0; col < width; col++) {
  320. for (k = 0; k < max_len; k++) {
  321. val_m[k] = val_p[k] = 0;
  322. }
  323. for (t = 0; t < height; t++) {
  324. src[t] = psrc[t * row_stride + col];
  325. }
  326. sp_p_idx = 0;
  327. sp_m_idx = height - 1;
  328. vp_idx = 0;
  329. vm_idx = height - 1;
  330. initial_p[0] = src[0];
  331. initial_m[0] = src[height - 1];
  332. for (row = 0; row < height; row++) {
  333. terms = (row < 4) ? row : 4;
  334. for (i = 0; i <= terms; i++) {
  335. val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i]
  336. * val_p[vp_idx - i];
  337. val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i]
  338. * val_m[vm_idx + i];
  339. }
  340. for (j = i; j <= 4; j++) {
  341. val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];
  342. val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];
  343. }
  344. sp_p_idx++;
  345. sp_m_idx--;
  346. vp_idx++;
  347. vm_idx--;
  348. }
  349. int i1, j1, k1, b;
  350. int bend = 1 * height;
  351. double sum;
  352. i1 = j1 = k1 = 0;
  353. for (b = 0; b < bend; b++) {
  354. sum = val_p[i1++] + val_m[j1++];
  355. if (sum > 255)
  356. sum = 255;
  357. else if (sum < 0)
  358. sum = 0;
  359. dst[k1++] = (int) sum;
  360. }
  361. for (t = 0; t < height; t++) {
  362. psrc[t * row_stride + col] = dst[t];
  363. }
  364. }
  365. }
  366. // 水平方向
  367. if (horz > 0.0) {
  368. horz = Math.abs(horz) + 1.0;
  369. if (horz != vert) {
  370. std_dev = Math.sqrt(-(horz * horz)
  371. / (2 * Math.log(1.0 / 255.0)));
  372. // 初试化常量
  373. findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);
  374. }
  375. for (row = 0; row < height; row++) {
  376. for (k = 0; k < max_len; k++) {
  377. val_m[k] = val_p[k] = 0;
  378. }
  379. for (t = 0; t < width; t++) {
  380. src[t] = psrc[row * row_stride + t];
  381. }
  382. sp_p_idx = 0;
  383. sp_m_idx = width - 1;
  384. vp_idx = 0;
  385. vm_idx = width - 1;
  386. initial_p[0] = src[0];
  387. initial_m[0] = src[width - 1];
  388. for (col = 0; col < width; col++) {
  389. terms = (col < 4) ? col : 4;
  390. for (i = 0; i <= terms; i++) {
  391. val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i]
  392. * val_p[vp_idx - i];
  393. val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i]
  394. * val_m[vm_idx + i];
  395. }
  396. for (j = i; j <= 4; j++) {
  397. val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];
  398. val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];
  399. }
  400. sp_p_idx++;
  401. sp_m_idx--;
  402. vp_idx++;
  403. vm_idx--;
  404. }
  405. int i1, j1, k1, b;
  406. int bend = 1 * width;
  407. double sum;
  408. i1 = j1 = k1 = 0;
  409. for (b = 0; b < bend; b++) {
  410. sum = val_p[i1++] + val_m[j1++];
  411. if (sum > 255)
  412. sum = 255;
  413. else if (sum < 0)
  414. sum = 0;
  415. dst[k1++] = (int) sum;
  416. }
  417. for (t = 0; t < width; t++) {
  418. psrc[row * row_stride + t] = dst[t];
  419. }
  420. }
  421. }
  422. return 0;
  423. }
  424. private void findConstants(double[] n_p, double[] n_m, double[] d_p,
  425. double[] d_m, double[] bd_p, double[] bd_m, double std_dev) {
  426. double div = Math.sqrt(2 * 3.141593) * std_dev;
  427. double x0 = -1.783 / std_dev;
  428. double x1 = -1.723 / std_dev;
  429. double x2 = 0.6318 / std_dev;
  430. double x3 = 1.997 / std_dev;
  431. double x4 = 1.6803 / div;
  432. double x5 = 3.735 / div;
  433. double x6 = -0.6803 / div;
  434. double x7 = -0.2598 / div;
  435. int i;
  436. n_p[0] = x4 + x6;
  437. n_p[1] = (Math.exp(x1)
  438. * (x7 * Math.sin(x3) - (x6 + 2 * x4) * Math.cos(x3)) + Math
  439. .exp(x0) * (x5 * Math.sin(x2) - (2 * x6 + x4) * Math.cos(x2)));
  440. n_p[2] = (2
  441. * Math.exp(x0 + x1)
  442. * ((x4 + x6) * Math.cos(x3) * Math.cos(x2) - x5 * Math.cos(x3)
  443. * Math.sin(x2) - x7 * Math.cos(x2) * Math.sin(x3)) + x6
  444. * Math.exp(2 * x0) + x4 * Math.exp(2 * x1));
  445. n_p[3] = (Math.exp(x1 + 2 * x0)
  446. * (x7 * Math.sin(x3) - x6 * Math.cos(x3)) + Math.exp(x0 + 2
  447. * x1)
  448. * (x5 * Math.sin(x2) - x4 * Math.cos(x2)));
  449. n_p[4] = 0.0;
  450. d_p[0] = 0.0;
  451. d_p[1] = -2 * Math.exp(x1) * Math.cos(x3) - 2 * Math.exp(x0)
  452. * Math.cos(x2);
  453. d_p[2] = 4 * Math.cos(x3) * Math.cos(x2) * Math.exp(x0 + x1)
  454. + Math.exp(2 * x1) + Math.exp(2 * x0);
  455. d_p[3] = -2 * Math.cos(x2) * Math.exp(x0 + 2 * x1) - 2 * Math.cos(x3)
  456. * Math.exp(x1 + 2 * x0);
  457. d_p[4] = Math.exp(2 * x0 + 2 * x1);
  458. for (i = 0; i <= 4; i++) {
  459. d_m[i] = d_p[i];
  460. }
  461. n_m[0] = 0.0;
  462. for (i = 1; i <= 4; i++) {
  463. n_m[i] = n_p[i] - d_p[i] * n_p[0];
  464. }
  465. double sum_n_p, sum_n_m, sum_d;
  466. double a, b;
  467. sum_n_p = 0.0;
  468. sum_n_m = 0.0;
  469. sum_d = 0.0;
  470. for (i = 0; i <= 4; i++) {
  471. sum_n_p += n_p[i];
  472. sum_n_m += n_m[i];
  473. sum_d += d_p[i];
  474. }
  475. a = sum_n_p / (1.0 + sum_d);
  476. b = sum_n_m / (1.0 + sum_d);
  477. for (i = 0; i <= 4; i++) {
  478. bd_p[i] = d_p[i] * a;
  479. bd_m[i] = d_m[i] * b;
  480. }
  481. }
  482. /**
  483. * 图片锐化(拉普拉斯变换)
  484. *
  485. * @param mBitmapSrc 图片源
  486. * @return Bitmap
  487. */
  488. public Bitmap sharpenImageAmeliorate(Bitmap mBitmapSrc) {
  489. // 拉普拉斯矩阵
  490. int[] laplacian = new int[]{-1, -1, -1, -1, 9, -1, -1, -1, -1};
  491. int width = mBitmapSrc.getWidth();
  492. int height = mBitmapSrc.getHeight();
  493. Bitmap bitmap = Bitmap.createBitmap(width, height,
  494. Bitmap.Config.RGB_565);
  495. int pixR = 0;
  496. int pixG = 0;
  497. int pixB = 0;
  498. int pixColor = 0;
  499. int newR = 0;
  500. int newG = 0;
  501. int newB = 0;
  502. int idx = 0;
  503. float alpha = 0.3F;
  504. int[] pixels = new int[width * height];
  505. mBitmapSrc.getPixels(pixels, 0, width, 0, 0, width, height);
  506. for (int i = 1, length = height - 1; i < length; i++) {
  507. for (int k = 1, len = width - 1; k < len; k++) {
  508. idx = 0;
  509. for (int m = -1; m <= 1; m++) {
  510. for (int n = -1; n <= 1; n++) {
  511. pixColor = pixels[(i + n) * width + k + m];
  512. pixR = Color.red(pixColor);
  513. pixG = Color.green(pixColor);
  514. pixB = Color.blue(pixColor);
  515. newR = newR + (int) (pixR * laplacian[idx] * alpha);
  516. newG = newG + (int) (pixG * laplacian[idx] * alpha);
  517. newB = newB + (int) (pixB * laplacian[idx] * alpha);
  518. idx++;
  519. }
  520. }
  521. newR = Math.min(255, Math.max(0, newR));
  522. newG = Math.min(255, Math.max(0, newG));
  523. newB = Math.min(255, Math.max(0, newB));
  524. pixels[i * width + k] = Color.argb(255, newR, newG, newB);
  525. newR = 0;
  526. newG = 0;
  527. newB = 0;
  528. }
  529. }
  530. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  531. return bitmap;
  532. }
  533. /**
  534. * 图片复古
  535. *
  536. * @param mBitmapSrc 图片源
  537. * @return Bitmap
  538. */
  539. public Bitmap oldRemeberImage(Bitmap mBitmapSrc) {
  540. /*
  541. * 怀旧处理算法即设置新的RGB
  542. * R=0.393r+0.769g+0.189b
  543. * G=0.349r+0.686g+0.168b
  544. * B=0.272r+0.534g+0.131b
  545. */
  546. int width = mBitmapSrc.getWidth();
  547. int height = mBitmapSrc.getHeight();
  548. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  549. int pixColor = 0;
  550. int pixR = 0;
  551. int pixG = 0;
  552. int pixB = 0;
  553. int newR = 0;
  554. int newG = 0;
  555. int newB = 0;
  556. int[] pixels = new int[width * height];
  557. mBitmapSrc.getPixels(pixels, 0, width, 0, 0, width, height);
  558. for (int i = 0; i < height; i++) {
  559. for (int k = 0; k < width; k++) {
  560. pixColor = pixels[width * i + k];
  561. pixR = Color.red(pixColor);
  562. pixG = Color.green(pixColor);
  563. pixB = Color.blue(pixColor);
  564. newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
  565. newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
  566. newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
  567. int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
  568. pixels[width * i + k] = newColor;
  569. }
  570. }
  571. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  572. return bitmap;
  573. }
  574. /**
  575. * 图片浮雕
  576. * 将当前像素点的RGB值分别与255之差后的值作为当前点的RGB
  577. * 灰度图像:通常使用的方法是gray=0.3*pixR+0.59*pixG+0.11*pixB
  578. *
  579. * @param mBitmapSrc 图片源
  580. * @return Bitmap
  581. */
  582. public Bitmap reliefImage(Bitmap mBitmapSrc) {
  583. /*
  584. * 算法原理:(前一个像素点RGB-当前像素点RGB+127)作为当前像素点RGB值
  585. * 在ABC中计算B点浮雕效果(RGB值在0~255)
  586. * B.r = C.r - B.r + 127
  587. * B.g = C.g - B.g + 127
  588. * B.b = C.b - B.b + 127
  589. */
  590. int width = mBitmapSrc.getWidth();
  591. int height = mBitmapSrc.getHeight();
  592. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  593. int pixColor = 0;
  594. int pixR = 0;
  595. int pixG = 0;
  596. int pixB = 0;
  597. int newR = 0;
  598. int newG = 0;
  599. int newB = 0;
  600. int[] pixels = new int[width * height];
  601. mBitmapSrc.getPixels(pixels, 0, width, 0, 0, width, height);
  602. for (int i = 1; i < height - 1; i++) {
  603. for (int k = 1; k < width - 1; k++) {
  604. //获取前一个像素颜色
  605. pixColor = pixels[width * i + k];
  606. pixR = Color.red(pixColor);
  607. pixG = Color.green(pixColor);
  608. pixB = Color.blue(pixColor);
  609. //获取当前像素
  610. pixColor = pixels[(width * i + k) + 1];
  611. newR = Color.red(pixColor) - pixR + 127;
  612. newG = Color.green(pixColor) - pixG + 127;
  613. newB = Color.blue(pixColor) - pixB + 127;
  614. newR = Math.min(255, Math.max(0, newR));
  615. newG = Math.min(255, Math.max(0, newG));
  616. newB = Math.min(255, Math.max(0, newB));
  617. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  618. }
  619. }
  620. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  621. return bitmap;
  622. }
  623. /**
  624. * 图片光照效果
  625. *
  626. * @param mBitmapSrc  图片源
  627. * @param position 光照位置 默认居中
  628. * @param strength    光照强度 100-150
  629. * @return Bitmap
  630. */
  631. public Bitmap sunshineImage(Bitmap mBitmapSrc, Position position, float strength) {
  632. /*
  633. * 算法原理:(前一个像素点RGB-当前像素点RGB+127)作为当前像素点RGB值
  634. * 在ABC中计算B点浮雕效果(RGB值在0~255)
  635. * B.r = C.r - B.r + 127
  636. * B.g = C.g - B.g + 127
  637. * B.b = C.b - B.b + 127
  638. * 光照中心取长宽较小值为半径,也可以自定义从左上角射过来
  639. */
  640. int width = mBitmapSrc.getWidth();
  641. int height = mBitmapSrc.getHeight();
  642. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  643. int pixColor = 0;
  644. int pixR = 0;
  645. int pixG = 0;
  646. int pixB = 0;
  647. int newR = 0;
  648. int newG = 0;
  649. int newB = 0;
  650. //光照
  651. int centerX;
  652. int centerY;
  653. if (position == Position.LEFT_DOWN){centerX = width * (1/4); centerY = height * (3/4);}
  654. else if (position == Position.LEFT_UP){centerX = width * (1/4); centerY = height * (1/4);}
  655. else if (position == Position.RIGHT_DOWN){centerX = width * (3/4); centerY = height * (3/4);}
  656. else if (position == Position.RIGHT_UP){centerX = width * (3/4); centerY = height * (1/4);}
  657. else {centerX = width / 2; centerY = height / 2;}//默认居中
  658. int radius = Math.min(centerX, centerY);
  659. int[] pixels = new int[width * height];
  660. mBitmapSrc.getPixels(pixels, 0, width, 0, 0, width, height);
  661. for (int i = 1; i < height - 1; i++) {
  662. for (int k = 1; k < width - 1; k++) {
  663. //获取前一个像素颜色
  664. pixColor = pixels[width * i + k];
  665. pixR = Color.red(pixColor);
  666. pixG = Color.green(pixColor);
  667. pixB = Color.blue(pixColor);
  668. newR = pixR;
  669. newG = pixG;
  670. newB = pixB;
  671. //计算当前点到光照中心的距离,平面坐标系中两点之间的距离
  672. int distance = (int) (Math.pow((centerY - i), 2) + Math.pow((centerX - k), 2));
  673. if (distance < radius * radius) {
  674. //按照距离大小计算增强的光照值
  675. int result = (int) (strength * (1.0 - Math.sqrt(distance) / radius));
  676. newR = pixR + result;
  677. newG = newG + result;
  678. newB = pixB + result;
  679. }
  680. newR = Math.min(255, Math.max(0, newR));
  681. newG = Math.min(255, Math.max(0, newG));
  682. newB = Math.min(255, Math.max(0, newB));
  683. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  684. }
  685. }
  686. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  687. return bitmap;
  688. }
  689. /**
  690. * 图片冰冻效果
  691. *
  692. * @param mBitmapSrc 图片源
  693. * @return Bitmap
  694. */
  695. public Bitmap iceImage(Bitmap mBitmapSrc) {
  696. int width = mBitmapSrc.getWidth();
  697. int height = mBitmapSrc.getHeight();
  698. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  699. int pixColor = 0;
  700. int pixR = 0;
  701. int pixG = 0;
  702. int pixB = 0;
  703. int newColor = 0;
  704. int newR = 0;
  705. int newG = 0;
  706. int newB = 0;
  707. int[] pixels = new int[width * height];
  708. mBitmapSrc.getPixels(pixels, 0, width, 0, 0, width, height);
  709. for (int i = 0; i < height; i++) {
  710. for (int k = 0; k < width; k++) {
  711. //获取前一个像素颜色
  712. pixColor = pixels[width * i + k];
  713. pixR = Color.red(pixColor);
  714. pixG = Color.green(pixColor);
  715. pixB = Color.blue(pixColor);
  716. //红色
  717. newColor = pixR - pixG - pixB;
  718. newColor = newColor * 3 / 2;
  719. if (newColor < 0) {
  720. newColor = -newColor;
  721. }
  722. if (newColor > 255) {
  723. newColor = 255;
  724. }
  725. newR = newColor;
  726. //绿色
  727. newColor = pixG - pixB - pixR;
  728. newColor = newColor * 3 / 2;
  729. if (newColor < 0) {
  730. newColor = -newColor;
  731. }
  732. if (newColor > 255) {
  733. newColor = 255;
  734. }
  735. newG = newColor;
  736. //蓝色
  737. newColor = pixB - pixG - pixR;
  738. newColor = newColor * 3 / 2;
  739. if (newColor < 0) {
  740. newColor = -newColor;
  741. }
  742. if (newColor > 255) {
  743. newColor = 255;
  744. }
  745. newB = newColor;
  746. pixels[width * i + k] = Color.argb(255, newR, newG, newB);
  747. }
  748. }
  749. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  750. return bitmap;
  751. }
  752. /**
  753. * 放大缩小图片
  754. *
  755. * @param mBitmapSrc 图片源
  756. * @param w          压缩后的宽度 负数时为反向
  757. * @param h          压缩后的高度 负数为反向
  758. * @return Bitmap
  759. */
  760. public Bitmap zoomBitmap(Bitmap mBitmapSrc, int w, int h) {
  761. int width = mBitmapSrc.getWidth();
  762. int height = mBitmapSrc.getHeight();
  763. Matrix matrix = new Matrix();
  764. float scaleWidth = ((float) w / width);
  765. float scaleHeight = ((float) h / height);
  766. matrix.postScale(scaleWidth, scaleHeight);
  767. return Bitmap.createBitmap(mBitmapSrc, 0, 0, width, height, matrix, true);
  768. }
  769. /**
  770. * 按比例放大缩小图片
  771. *
  772. * @param mBitmapSrc  图片源
  773. * @param widthScale  宽缩放比
  774. * @param heightScale 高缩放比
  775. * @return Bitmap
  776. */
  777. public Bitmap zoomBitmap(Bitmap mBitmapSrc, float widthScale, float heightScale) {
  778. Matrix matrix = new Matrix();
  779. matrix.postScale(widthScale, heightScale);
  780. return Bitmap.createBitmap(mBitmapSrc, 0, 0, mBitmapSrc.getWidth(), mBitmapSrc.getHeight(), matrix, true);
  781. }
  782. /**
  783. * 将Drawable转化为Bitmap
  784. *
  785. * @param mDrawableSrc 要转化的源drawable
  786. * @return Bitmap
  787. */
  788. public Bitmap drawableToBitmap(Drawable mDrawableSrc) {
  789. int width = mDrawableSrc.getIntrinsicWidth();
  790. int height = mDrawableSrc.getIntrinsicHeight();
  791. Bitmap bitmap = Bitmap.createBitmap(width, height,
  792. mDrawableSrc.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
  793. : Bitmap.Config.RGB_565);
  794. Canvas canvas = new Canvas(bitmap);
  795. mDrawableSrc.setBounds(0, 0, width, height);
  796. mDrawableSrc.draw(canvas);
  797. return bitmap;
  798. }
  799. /**
  800. * 倒影图片
  801. *
  802. * @param mBitmapSrc 图片源
  803. * @return Bitmap
  804. */
  805. public Bitmap toReflectedImage(Bitmap mBitmapSrc) {
  806. final int reflectionGap = 4;
  807. int width = mBitmapSrc.getWidth();
  808. int height = mBitmapSrc.getHeight();
  809. Matrix matrix = new Matrix();
  810. matrix.preScale(1, -1);
  811. Bitmap reflectionImage = Bitmap.createBitmap(mBitmapSrc, 0,
  812. height / 2, width, height / 2, matrix, false);
  813. Bitmap bitmap = Bitmap.createBitmap(width,
  814. (height + height / 2), Bitmap.Config.ARGB_8888);
  815. Canvas canvas = new Canvas(bitmap);
  816. canvas.drawBitmap(mBitmapSrc, 0, 0, null);
  817. Paint defaultPaint = new Paint();
  818. canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);
  819. canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
  820. Paint paint = new Paint();
  821. LinearGradient shader = new LinearGradient(0,
  822. mBitmapSrc.getHeight(), 0, bitmap.getHeight()
  823. + reflectionGap, 0x70FFFFFF, 0x00FFFFFF,
  824. Shader.TileMode.MIRROR);
  825. paint.setShader(shader);
  826. paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
  827. canvas.drawRect(0, height, width, bitmap.getHeight()
  828. + reflectionGap, paint);
  829. return bitmap;
  830. }
  831. /**
  832. * 水印特效
  833. *
  834. * @param mBitmapSrc   图片源
  835. * @param waterMarkSrc Bitmap
  836. * @return Bitmap
  837. */
  838. public Bitmap createBitmapWithWatermark(Bitmap mBitmapSrc, Bitmap waterMarkSrc, Position position) {
  839. if (mBitmapSrc == null) {
  840. return null;
  841. }
  842. int w = mBitmapSrc.getWidth();
  843. int h = mBitmapSrc.getHeight();
  844. int ww = waterMarkSrc.getWidth();
  845. int wh = waterMarkSrc.getHeight();
  846. Bitmap newBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图
  847. Canvas cv = new Canvas(newBitmap);
  848. cv.drawBitmap(mBitmapSrc, 0, 0, null);// 在 0,0坐标开始画入src
  849. if (position == Position.RIGHT_DOWN)
  850. cv.drawBitmap(waterMarkSrc, w - ww + 5, h - wh + 5, null);// 在src的右下角画入水印
  851. else if (position == Position.RIGHT_UP)
  852. cv.drawBitmap(waterMarkSrc, w - ww + 5, 5, null);// 在src的右上角画入水印
  853. else if (position == Position.LEFT_DOWN)
  854. cv.drawBitmap(waterMarkSrc, 5, h - wh + 5, null);// 在src的左下角画入水印
  855. else if (position == Position.LEFT_UP)
  856. cv.drawBitmap(waterMarkSrc, 5, 5, null);// 在src的左上角画入水印
  857. else
  858. cv.drawBitmap(waterMarkSrc, w/2 - ww/2, h/2 - wh, null);// 在src的中间画入水印
  859. cv.save(Canvas.ALL_SAVE_FLAG);// 保存
  860. cv.restore();// 存储
  861. return newBitmap;
  862. }
  863. /**
  864. * 获取缩略图
  865. * 默认获取的宽高为 100
  866. *
  867. * @param mBitmapSrc 图片源
  868. * @param width      int
  869. * @param height     int
  870. * @return Bitmap
  871. */
  872. public Bitmap getThumbBitmap(Bitmap mBitmapSrc, int width, int height) {
  873. if (width == 0) width = 100;
  874. if (height == 0) height = 100;
  875. Bitmap thumbBitmap;
  876. thumbBitmap = ThumbnailUtils.extractThumbnail(mBitmapSrc, width, height);
  877. return thumbBitmap;
  878. }
  879. /**
  880. * 黑白照片
  881. *
  882. * @param mBitmapSrc 图片源
  883. * @return Bitmap
  884. */
  885. public Bitmap toBlackAndWhite(Bitmap mBitmapSrc) {
  886. int mBitmapWidth;
  887. int mBitmapHeight;
  888. mBitmapWidth = mBitmapSrc.getWidth();
  889. mBitmapHeight = mBitmapSrc.getHeight();
  890. Bitmap bitmap = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight,
  891. Bitmap.Config.ARGB_8888);
  892. int iPixel;
  893. for (int i = 0; i < mBitmapWidth; i++) {
  894. for (int j = 0; j < mBitmapHeight; j++) {
  895. int curr_color = mBitmapSrc.getPixel(i, j);
  896. int avg = (Color.red(curr_color) + Color.green(curr_color) + Color
  897. .blue(curr_color)) / 3;
  898. if (avg >= 100) {
  899. iPixel = 255;
  900. } else {
  901. iPixel = 0;
  902. }
  903. int modify_color = Color.argb(255, iPixel, iPixel, iPixel);
  904. bitmap.setPixel(i, j, modify_color);
  905. }
  906. }
  907. return bitmap;
  908. }
  909. /**
  910. * 底片效果
  911. *
  912. * @param mBitmapSrc 图片源
  913. * @return Bitmap
  914. */
  915. private Bitmap negativeFilm(Bitmap mBitmapSrc) {
  916. // RGBA的最大值
  917. final int MAX_VALUE = 255;
  918. int width = mBitmapSrc.getWidth();
  919. int height = mBitmapSrc.getHeight();
  920. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  921. int pixR;
  922. int pixG;
  923. int pixB;
  924. int pixColor;
  925. int newR;
  926. int newG;
  927. int newB;
  928. int[] pixels = new int[width * height];
  929. mBitmapSrc.getPixels(pixels, 0, width, 0, 0, width, height);
  930. int pos = 0;
  931. for (int i = 1, length = height - 1; i < length; i++) {
  932. for (int k = 1, len = width - 1; k < len; k++) {
  933. pos = i * width + k;
  934. pixColor = pixels[pos];
  935. pixR = Color.red(pixColor);
  936. pixG = Color.green(pixColor);
  937. pixB = Color.blue(pixColor);
  938. newR = MAX_VALUE - pixR;
  939. newG = MAX_VALUE - pixG;
  940. newB = MAX_VALUE - pixB;
  941. newR = Math.min(MAX_VALUE, Math.max(0, newR));
  942. newG = Math.min(MAX_VALUE, Math.max(0, newG));
  943. newB = Math.min(MAX_VALUE, Math.max(0, newB));
  944. pixels[pos] = Color.argb(MAX_VALUE, newR, newG, newB);
  945. }
  946. }
  947. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  948. return bitmap;
  949. }
  950. /**
  951. * 油画效果
  952. *
  953. * @param mBitmapSrc 图片源
  954. * @return Bitmap
  955. */
  956. public Bitmap oilPainting(Bitmap mBitmapSrc) {
  957. Bitmap bmpReturn = Bitmap.createBitmap(mBitmapSrc.getWidth(),
  958. mBitmapSrc.getHeight(), Bitmap.Config.RGB_565);
  959. int color = 0;
  960. int Radio = 0;
  961. int width = mBitmapSrc.getWidth();
  962. int height = mBitmapSrc.getHeight();
  963. Random rnd = new Random();
  964. int iModel = 10;
  965. int i = width - iModel;
  966. while (i > 1) {
  967. int j = height - iModel;
  968. while (j > 1) {
  969. int iPos = rnd.nextInt(100000) % iModel;
  970. color = mBitmapSrc.getPixel(i + iPos, j + iPos);
  971. bmpReturn.setPixel(i, j, color);
  972. j = j - 1;
  973. }
  974. i = i - 1;
  975. }
  976. return bmpReturn;
  977. }
  978. /**
  979. * 图片合成
  980. *
  981. * @param position   组合位置: -1 :左   1 :右   2 :上   -2 :下
  982. * @param mBitmapSrcs 图片源
  983. * @return Bitmap
  984. */
  985. public Bitmap photoMix(Position position, Bitmap... mBitmapSrcs) {
  986. if (mBitmapSrcs.length <= 0) {
  987. return null;
  988. }
  989. if (mBitmapSrcs.length == 1) {
  990. return mBitmapSrcs[0];
  991. }
  992. Bitmap newBitmap = mBitmapSrcs[0];
  993. for (int i = 1; i < mBitmapSrcs.length; i++) {
  994. newBitmap = createBitmapForPhotoMix(newBitmap, mBitmapSrcs[i], position);
  995. }
  996. return newBitmap;
  997. }
  998. private Bitmap createBitmapForPhotoMix(Bitmap first, Bitmap second, Position position) {
  999. if (first == null) {
  1000. return null;
  1001. }
  1002. if (second == null) {
  1003. return first;
  1004. }
  1005. int fw = first.getWidth();
  1006. int fh = first.getHeight();
  1007. int sw = second.getWidth();
  1008. int sh = second.getHeight();
  1009. Bitmap newBitmap = null;
  1010. if (position == Position.LEFT) {
  1011. newBitmap = Bitmap.createBitmap(fw + sw, fh > sh ? fh : sh, Bitmap.Config.ARGB_8888);
  1012. Canvas canvas = new Canvas(newBitmap);
  1013. canvas.drawBitmap(first, sw, 0, null);
  1014. canvas.drawBitmap(second, 0, 0, null);
  1015. } else if (position == Position.RIGHT) {
  1016. newBitmap = Bitmap.createBitmap(fw + sw, fh > sh ? fh : sh, Bitmap.Config.ARGB_8888);
  1017. Canvas canvas = new Canvas(newBitmap);
  1018. canvas.drawBitmap(first, 0, 0, null);
  1019. canvas.drawBitmap(second, fw, 0, null);
  1020. } else if (position == Position.TOP) {
  1021. newBitmap = Bitmap.createBitmap(sw > fw ? sw : fw, fh + sh, Bitmap.Config.ARGB_8888);
  1022. Canvas canvas = new Canvas(newBitmap);
  1023. canvas.drawBitmap(first, 0, sh, null);
  1024. canvas.drawBitmap(second, 0, 0, null);
  1025. } else if (position ==  Position.BOTTOM) {
  1026. newBitmap = Bitmap.createBitmap(sw > fw ? sw : fw, fh + sh, Bitmap.Config.ARGB_8888);
  1027. Canvas canvas = new Canvas(newBitmap);
  1028. canvas.drawBitmap(first, 0, 0, null);
  1029. canvas.drawBitmap(second, 0, fh, null);
  1030. } else if (position ==  Position.CENTRE) {
  1031. newBitmap = Bitmap.createBitmap(Math.max(fw, sw), Math.max(fw, sw), Bitmap.Config.ARGB_8888);
  1032. Canvas canvas = new Canvas(newBitmap);
  1033. canvas.drawBitmap(first, 0, 0, null);
  1034. canvas.drawBitmap(second, fw / 2, fh / 2, null);
  1035. }
  1036. return newBitmap;
  1037. }
  1038. /**
  1039. * bitmap 位图保存成文件
  1040. *
  1041. * @param mBitmapSrc 图片源
  1042. * @param fileName   文件名
  1043. * @param filePath   保存的文件路径(默认为空时在内存根目录)
  1044. * @param format     保存的图片格式(默认 JPEG)
  1045. */
  1046. public void saveBitmap2File(Bitmap mBitmapSrc, String fileName, String filePath, Format format) {
  1047. String suffix = "jpg";
  1048. if (TextUtils.isEmpty(filePath))
  1049. filePath = Environment.getExternalStorageDirectory().getAbsolutePath().toString();
  1050. Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;
  1051. if (format == Format.JPEG){
  1052. compressFormat = Bitmap.CompressFormat.JPEG;
  1053. suffix = ".jpeg";
  1054. }
  1055. else if (format == Format.PNG){
  1056. compressFormat = Bitmap.CompressFormat.PNG;
  1057. suffix = ".png";
  1058. }
  1059. else if (format == Format.WEBP){
  1060. compressFormat = Bitmap.CompressFormat.WEBP;
  1061. suffix = ".webp";
  1062. }
  1063. File file = new File(filePath + File.separator, fileName + suffix);
  1064. try {
  1065. file.createNewFile();
  1066. OutputStream os = new FileOutputStream(file);
  1067. mBitmapSrc.compress(compressFormat, 100, os);
  1068. os.flush();
  1069. } catch (IOException e) {
  1070. e.printStackTrace();
  1071. }
  1072. }
  1073. /**
  1074. * 图片平滑处理
  1075. * 3*3掩模处理(平均处理),降低噪声
  1076. *
  1077. * @param mBitmapSrc 图片源
  1078. * @return Bitmap
  1079. */
  1080. public Bitmap smoothImage(Bitmap mBitmapSrc) {
  1081. int w = mBitmapSrc.getWidth();
  1082. int h = mBitmapSrc.getHeight();
  1083. int[] data = new int[w * h];
  1084. mBitmapSrc.getPixels(data, 0, w, 0, 0, w, h);
  1085. int[] resultData = new int[w * h];
  1086. try {
  1087. resultData = filter(data, w, h);
  1088. } catch (Exception e) {
  1089. e.printStackTrace();
  1090. }
  1091. Bitmap newBitmap = Bitmap.createBitmap(resultData, w, h, Bitmap.Config.ARGB_8888);
  1092. return newBitmap;
  1093. }
  1094. private int[] filter(int[] data, int width, int height) throws Exception {
  1095. int filterData[] = new int[data.length];
  1096. int min = 10000;
  1097. int max = -10000;
  1098. if (data.length != width * height) return filterData;
  1099. try {
  1100. for (int i = 0; i < height; i++) {
  1101. for (int j = 0; j < width; j++) {
  1102. if (i == 0 || i == 1 || i == height - 1 || i == height - 2 || j == 0 || j == 1 || j == width - 1 || j == width - 2) {
  1103. filterData[i * width + j] = data[i * width + j];
  1104. } else {
  1105. double average;             //中心的九个像素点
  1106. average = (data[i * width + j] + data[i * width + j - 1] + data[i * width + j + 1]
  1107. + data[(i - 1) * width + j] + data[(i - 1) * width + j - 1] + data[(i - 1) * width + j + 1]
  1108. + data[(i + 1) * width + j] + data[(i + 1) * width + j - 1] + data[(i + 1) * width + j + 1]) / 9;
  1109. filterData[i * width + j] = (int) (average);
  1110. }
  1111. if (filterData[i * width + j] < min)
  1112. min = filterData[i * width + j];
  1113. if (filterData[i * width + j] > max)
  1114. max = filterData[i * width + j];
  1115. }
  1116. }
  1117. for (int i = 0; i < width * height; i++) {
  1118. filterData[i] = (filterData[i] - min) * 255 / (max - min);
  1119. }
  1120. } catch (Exception e) {
  1121. e.printStackTrace();
  1122. throw new Exception(e);
  1123. }
  1124. return filterData;
  1125. }
  1126. /**
  1127. * 图片增亮
  1128. *
  1129. * @param mBitmapSrc     图片源
  1130. * @param brightenOffset 增加的亮度值
  1131. * @return Bitmap
  1132. */
  1133. public Bitmap brightenBitmap(Bitmap mBitmapSrc, int brightenOffset) {
  1134. int width = mBitmapSrc.getWidth();
  1135. int height = mBitmapSrc.getHeight();
  1136. int[] pix = new int[width * height];
  1137. mBitmapSrc.getPixels(pix, 0, width, 0, 0, width, height);
  1138. // Apply pixel-by-pixel change
  1139. int index = 0;
  1140. for (int y = 0; y < height; y++) {
  1141. for (int x = 0; x < width; x++) {
  1142. int r = (pix[index] >> 16) & 0xff;
  1143. int g = (pix[index] >> 8) & 0xff;
  1144. int b = pix[index] & 0xff;
  1145. r = Math.max(0, Math.min(255, r + brightenOffset));
  1146. g = Math.max(0, Math.min(255, g + brightenOffset));
  1147. b = Math.max(0, Math.min(255, b + brightenOffset));
  1148. pix[index] = 0xff000000 | (r << 16) | (g << 8) | b;
  1149. index++;
  1150. } // x
  1151. } // y
  1152. // Change bitmap to use new array
  1153. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  1154. bitmap.setPixels(pix, 0, width, 0, 0, width, height);
  1155. mBitmapSrc = null;
  1156. pix = null;
  1157. return bitmap;
  1158. }
  1159. /**
  1160. * 均值滤波
  1161. *
  1162. * @param mBitmapSrc   图片源
  1163. * @param filterWidth  滤波宽度值
  1164. * @param filterHeight 滤波高度值
  1165. */
  1166. public Bitmap averageFilter(Bitmap mBitmapSrc, int filterWidth, int filterHeight) {
  1167. int width = mBitmapSrc.getWidth();
  1168. int height = mBitmapSrc.getHeight();
  1169. int[] pixNew = new int[width * height];
  1170. int[] pixOld = new int[width * height];
  1171. mBitmapSrc.getPixels(pixNew, 0, width, 0, 0, width, height);
  1172. mBitmapSrc.getPixels(pixOld, 0, width, 0, 0, width, height);
  1173. // Apply pixel-by-pixel change
  1174. int filterHalfWidth = filterWidth / 2;
  1175. int filterHalfHeight = filterHeight / 2;
  1176. int filterArea = filterWidth * filterHeight;
  1177. for (int y = filterHalfHeight; y < height - filterHalfHeight; y++) {
  1178. for (int x = filterHalfWidth; x < width - filterHalfWidth; x++) {
  1179. // Accumulate values in neighborhood
  1180. int accumR = 0, accumG = 0, accumB = 0;
  1181. for (int dy = -filterHalfHeight; dy <= filterHalfHeight; dy++) {
  1182. for (int dx = -filterHalfWidth; dx <= filterHalfWidth; dx++) {
  1183. int index = (y + dy) * width + (x + dx);
  1184. accumR += (pixOld[index] >> 16) & 0xff;
  1185. accumG += (pixOld[index] >> 8) & 0xff;
  1186. accumB += pixOld[index] & 0xff;
  1187. } // dx
  1188. } // dy
  1189. // Normalize
  1190. accumR /= filterArea;
  1191. accumG /= filterArea;
  1192. accumB /= filterArea;
  1193. int index = y * width + x;
  1194. pixNew[index] = 0xff000000 | (accumR << 16) | (accumG << 8) | accumB;
  1195. } // x
  1196. } // y
  1197. // Change bitmap to use new array
  1198. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  1199. bitmap.setPixels(pixNew, 0, width, 0, 0, width, height);
  1200. mBitmapSrc = null;
  1201. pixOld = null;
  1202. pixNew = null;
  1203. return bitmap;
  1204. }
  1205. /**
  1206. * 中值滤波
  1207. *
  1208. * @param mBitmapSrc   图片源
  1209. * @param filterWidth  滤波宽度值
  1210. * @param filterHeight 滤波高度值
  1211. */
  1212. public Bitmap medianFilter(Bitmap mBitmapSrc, int filterWidth, int filterHeight) {
  1213. int width = mBitmapSrc.getWidth();
  1214. int height = mBitmapSrc.getHeight();
  1215. int[] pixNew = new int[width * height];
  1216. int[] pixOld = new int[width * height];
  1217. mBitmapSrc.getPixels(pixNew, 0, width, 0, 0, width, height);
  1218. mBitmapSrc.getPixels(pixOld, 0, width, 0, 0, width, height);
  1219. // Apply pixel-by-pixel change
  1220. int filterHalfWidth = filterWidth / 2;
  1221. int filterHalfHeight = filterHeight / 2;
  1222. int filterArea = filterWidth * filterHeight;
  1223. for (int y = filterHalfHeight; y < height - filterHalfHeight; y++) {
  1224. for (int x = filterHalfWidth; x < width - filterHalfWidth; x++) {
  1225. // Accumulate values in neighborhood
  1226. int accumR = 0, accumG = 0, accumB = 0;
  1227. for (int dy = -filterHalfHeight; dy <= filterHalfHeight; dy++) {
  1228. for (int dx = -filterHalfWidth; dx <= filterHalfWidth; dx++) {
  1229. int index = (y + dy) * width + (x + dx);
  1230. accumR += (pixOld[index] >> 16) & 0xff;
  1231. accumG += (pixOld[index] >> 8) & 0xff;
  1232. accumB += pixOld[index] & 0xff;
  1233. } // dx
  1234. } // dy
  1235. // Normalize
  1236. accumR /= filterArea;
  1237. accumG /= filterArea;
  1238. accumB /= filterArea;
  1239. int index = y * width + x;
  1240. pixNew[index] = 0xff000000 | (accumR << 16) | (accumG << 8) | accumB;
  1241. } // x
  1242. } // y
  1243. // Change bitmap to use new array
  1244. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
  1245. bitmap.setPixels(pixNew, 0, width, 0, 0, width, height);
  1246. mBitmapSrc = null;
  1247. pixOld = null;
  1248. pixNew = null;
  1249. return bitmap;
  1250. }
  1251. }

DEMO下载地址:Download

Android图像处理整理相关推荐

  1. android图像处理系列之五-- 给图片添加边框(中)

    前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水 ...

  2. android 涂鸦之图片叠加,android图像处理系列之七--图片涂鸦,水印-图片叠加...

    图片涂鸦和水印其实是一个功能,实现的方式是一样的,就是一张大图片和一张小点图片叠加即可.前面在android图像处理系列之六--给图片添加边框(下)-图片叠加中也讲到了图片叠加,里面实现的原理是直接操 ...

  3. Android图像处理-像素化的原理及实现

    原文地址:Android图像处理-像素化的原理及实现 博客地址:xiazdong.github.io 马赛克算法首先需要确定马赛克单元的大小,即小方块的大小.马赛克图的每个马赛克单元都是纯色的块,其取 ...

  4. 客户端+调用+matlab,基于web的android图像处理示范(Win7+Apache+PHP+Matlab+Android)

    基于web的android图像处理示例(Win7+Apache+PHP+Matlab+Android) 本文将介绍C/S模式的图像处理系统.C/S的框架已经在[1]中作了简单的介绍.[2]中介绍了如何 ...

  5. Android 图像处理软件

    原文出处:http://blog.csdn.net/mc_hust/article/details/43708163 在机器视觉实验室呆了有一年半时间了,但由于自己"任性".一直以 ...

  6. android图像边缘检测,Android图像处理系统1.4图像的锐化-边缘检测

    Android图像处理系统1.4图像的锐化-边缘检测 图像的锐化-边缘检测:(Robert Gradient.Sobel Gradient.Laplace Gradient) @author:郑海波 ...

  7. qemu安装android系统文档整理

    qemu安装android系统文档整理 准备工作 需要安装VMware Workstation Pro,Ubuntu 14.04.5 LTS,qemu开源虚拟机,android-x86-4.0-RC2 ...

  8. android图像处理系列之五--给图片添加边框(中)

    前面一篇讲到给图片加边框的方式,只能给图片加一些有规则的边框,如果想加一些比较精美的效果,就有点麻烦了.下面就给出解决这个问题的思路. 思路是:一些比较精美的花边图片我们是很难用代码控制,就目前本人水 ...

  9. 基于QProbe创建基本Android图像处理框架

    先来看一个GIF 这个GIF中有以下几个值得注意的地方 这个界面是基本的主要界面所应该在的地方.其右下角有一个"+"号,点击后,打开图像采集界面 在这个界面最上面的地方,显示的是当 ...

最新文章

  1. 越南71岁的工程师,给全世界的机械人送了一份大礼!
  2. 推荐5款好用的Linux音乐播放器
  3. mysql创建定时器(event),查看定时器,打开定时器,设置定时器时间
  4. selenium:断言
  5. 如何开启VMware串口
  6. 游戏开发设计模式(一):单例模式
  7. 数学建模之lingo使用
  8. 求大佬发一个unity curvy的资源包啊
  9. iphone11 android,iphone11launcher
  10. 单片机 C语言 读引脚,单片机引脚读写操作
  11. 智慧高铁、智慧机场对护照阅读器的应用 SDK说明
  12. php 5.6 语法,在PHP 5.6及以上版本中,还可以使用“...”语法实现可变参数列表。...
  13. hdu 校赛 油菜花王国
  14. zookeeper集群部署
  15. 传智播客管家婆java答案_传智播客黑马19年Java全(IDEA) [230G]|百度云|天翼云|GD|OD...
  16. centos 安装flash插件
  17. 全球及中国载药微球经肝动脉化学栓塞术(DEB-TACE)在肿瘤学中的应用行业研究及十四五规划分析报告
  18. IEEE期刊LaTeX模板
  19. 谷歌浏览器内核Cef js代码整理(一)
  20. 血流动力学相关概念和定律

热门文章

  1. openstack(Queens版) 安装FWaaS
  2. matlab 图像显著性检测ft_图像显著性检测总结
  3. 解决IndexClosedException: closed
  4. android绘制高亮区域,实现高亮某行的RecyclerView效果
  5. pandorabox php7,【恐惧交响4之潘多拉】ProjectSAM Symphobia 4 Pandora v1.0.7
  6. 未来计算机能帮人们做什么,未来的计算机阅读答案
  7. 孙连伟 java_java(jsp)简单实现数据库学生信息的增删改查案例
  8. linux mysql root修复_linux下误删mysql的root用户,解决方法
  9. 把iPhone充电口改成Type-C,卖了56万!
  10. 皮一皮:现在当爹妈的不容易...