Android图像处理整理

 

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

以下是参考文献:

点击打开链接

点击打开链接

点击打开链接

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

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

1、圆角图片

[java]  view plain  copy
  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(00, bmp.getWidth(), bmp.getHeight());  
  16.         final RectF rectF = new RectF(rect);  
  17.         paint.setAntiAlias(true);  
  18.         canvas.drawARGB(0000);  
  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 plain  copy
  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, 00, paint);  
  21.         return bmpGray;  
  22.     }  

3、线性灰度化

[java]  view plain  copy
  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.   
  31.                 if (green >= 255) {  
  32.                     green = 255;  
  33.                 }  
  34.   
  35.                 if (blue >= 255) {  
  36.                     blue = 255;  
  37.                 }  
  38.                 // 新的ARGB  
  39.                 int newColor = alpha | (red << 16) | (green << 8) | blue;  
  40.                 // 设置新图像的RGB值  
  41.                 linegray.setPixel(i, j, newColor);  
  42.             }  
  43.         }  
  44.         return linegray;  
  45.     }  

4、图片二值化

[java]  view plain  copy
  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 plain  copy
  1. /** 
  2.      * 高斯模糊 
  3.      *  
  4.      * @param bmp 
  5.      * @return 
  6.      */  
  7.     public static Bitmap convertToBlur(Bitmap bmp) {  
  8.         // 高斯矩阵  
  9.         int[] gauss = new int[] { 121242121 };  
  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, 00, 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, 00, width, height);  
  53.         return newBmp;  
  54.     }  

6、素描效果

[java]  view plain  copy
  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, 00, 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.05.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, 00, 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 plain  copy
  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, -19, -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, 00, 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, 00, width, height);  
  50.         return bitmap;  
  51.     }  

8、怀旧

[java]  view plain  copy
  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, 00, 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, 00, width, height);  
  37.       return bitmap;  
  38.     }  

9、浮雕

[java]  view plain  copy
  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, 00, 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, 00, width, height);  
  46.       return bitmap;  
  47.     }  

10、光照效果

[java]  view plain  copy
  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, 00, 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, 00, width, height);  
  58.       return bitmap;  
  59.     }  

11、冰冻效果

[java]  view plain  copy
  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, 00, 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, 00, width, height);  
  60.       return bitmap;  
  61.     }  

12、直方图均值化

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

猜你喜欢

转载自blog.csdn.net/u011228868/article/details/79226683