Android图片印刻,阳刻,素描图效果处理
2016-06-19 19:52
417 查看
介绍我参与开发的妙趣剪纸app使用的图片处理相关的技术
关于妙趣剪纸,各大android商店都可以下载,下面贴出小米商店的链接
妙趣剪纸下载软件效果截图
如何实现上面的图片处理效果呢
1.初始化高斯矩阵
ProcessFactory.IniGauss_2(ProcessFactory.gauss_radius); //初始化高斯矩阵
2.转化为灰度图
Bitmap bmpGrayscale=ProcessFactory.toGray2(activity.imageBmp); //转化为灰度图
3.反色
Bitmap bmpGauss=ProcessFactory.toInverse(bmpGrayscale); //反色
4.高斯模糊
bmpGauss=ProcessFactory.toGauss(bmpGauss); //高斯模糊
5.处理颜色减淡生成素描图
toColorDodge()函数
/** * 处理颜色减淡 * @param bmpGauss 高斯模糊完毕的图像 * @param bmpGrayscale 灰度图像 * @return */ // 在原先的灰度图上做颜色减淡,使用反色高斯图辅助```
bmpPapercut=ProcessFactory.toColorDodge(bmpGauss,bmpGrayscale); // TODO bmpColorDodge 图即为素描图
6.papercut处理
bmpPapercut=ProcessFactory.toPapercut(bmpPapercut);
7.膨胀处理
bmpPapercut = ProcessFactory.toPengzhang(bmpPapercut);for(int i = 0; i < 2; i++) { bmpPapercut = ProcessFactory.toPengzhang(bmpPapercut); }
8.腐蚀处理
for(int i = 0; i < 2; i++) { bmpPapercut = ProcessFactory.toFushi(bmpPapercut); }
9.frame处理
Bitmap min_img = ProcessFactory.toFramed(bmpPapercut);
最终阳刻算法结束
下面介绍印刻的处理算法
1.初始化高斯矩阵
ProcessFactory.IniGauss_2(ProcessFactory.gauss_radius); //初始化高斯矩阵
2.转化为灰度图
Bitmap bmpGrayscale=ProcessFactory.toGray2(activity.imageBmp); //转化为灰度图
3.反色
Bitmap bmpGauss=ProcessFactory.toInverse(bmpGrayscale); //反色
4.高斯模糊
bmpGauss=ProcessFactory.toGauss(bmpGauss); //高斯模糊
5.处理颜色减淡生成素描图
toColorDodge()函数
/** * 处理颜色减淡 * @param bmpGauss 高斯模糊完毕的图像 * @param bmpGrayscale 灰度图像 * @return */ // 在原先的灰度图上做颜色减淡,使用反色高斯图辅助```
bmpPapercut=ProcessFactory.toColorDodge(bmpGauss,bmpGrayscale); // TODO bmpColorDodge 图即为素描图
6.印刻处理
bmpPapercut=ProcessFactory.toYinkePapercut(bmpPapercut);
7.腐蚀处理
for(int i = 0; i < 2; i++) bmpPapercut = ProcessFactory.toFushi(bmpPapercut);
印刻结束,可以看出来,印刻和阳刻的前五步基本一样
工具类是ProcessFactory,上面用到的所有函数的定义都在里面可以找到
部分关键代码贴出,如果进一步交流,请加我下面的微信
/** * 初始化高斯矩阵 * @param fi */ public static void IniGauss_2(int fi) { toOne = 0; //一定要对此变量进行初始化操作! GAUSS = new double[(fi*2+1)*(fi*2+1)]; int index = 0; for (int x=-fi; x<=fi; x++){ for (int y=-fi; y<=fi; y++){ double sqrtFi = sigma*sigma; double ex = Math.pow(Math.E, (-(double)(x*x + y*y)/(2*(double)sqrtFi))); double result = ex/(double)(2 * Math.PI * sqrtFi); GAUSS[index] = result; toOne += result; index++; //MessageBox.Show(result.ToString()); } } for (int i = 0; i < index; i++){ GAUSS[i] = GAUSS[i] / toOne; //System.out.println("GAUSS["+i+"] = " + GAUSS[i]); } double sum = 0; for( double i : GAUSS) { sum += i; } //System.out.println("sum is"+sum); } /** * 取灰度图像函数1 * @param bmpOriginal * @return */ public static Bitmap toGray1(Bitmap bmpOriginal){ int width = bmpOriginal.getWidth(); //获取位图的宽 int height = bmpOriginal.getHeight(); //获取位图的高 int[] pixels = new int[width*height]; //通过位图的大小创建像素点数组 bmpOriginal.getPixels(pixels, 0, width, 0, 0, width, height); int alpha = (pixels[0] & 0xFF000000)>>24; //int alpha = (byte)0xFF; for(int i = 0; i < height; i++){ for(int j = 0; j < width; j++){ int pixel_src = pixels[width * i + j]; int red = (pixel_src & 0x00FF0000 ) >> 16; int green = (pixel_src & 0x0000FF00) >> 8; int blue = pixel_src & 0x000000FF; //注意需要先转换成float类型 int pixel_gray = (int)(((float)red) * 0.299 + ((float)green) * 0.587 + ((float)blue) * 0.114); int pixel_output = ((alpha <<24) & 0xFF000000) | ((pixel_gray << 16) & 0x00FF0000) | ((pixel_gray << 8) & 0x0000FF00) | (pixel_gray & 0x000000FF); pixels[width * i + j] = pixel_output; } } Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Config.ARGB_8888); bmpGrayscale.setPixels(pixels, 0, width, 0, 0, width, height); return bmpGrayscale; //bmpOriginal.setPixels(pixels, 0, width, 0, 0, width, height); //return bmpOriginal; } // public static Bitmap toGray5(Bitmap bmpOriginal){ // int row; // int pixel; // int R, G, B, A = 255; // // int width = bmpOriginal.getWidth(); //获取位图的宽 // int height = bmpOriginal.getHeight(); //获取位图的高 // int[] pixels = new int[width*height]; //通过位图的大小创建像素点数组 // bmpOriginal.getPixels(pixels, 0, width, 0, 0, width, height); // // for(int i = 0; i < height; i++) // { // row = width * i; // for(int j = 0; j < width; j++) // { // int pixel_src = pixels[row + j]; // // R = (pixel_src & 0x00FF0000 ) >> 16; // G = (pixel_src & 0x0000FF00) >> 8; // B = pixel_src & 0x000000FF; // // pixel = (int)(R * 0.299 + G * 0.587 + B * 0.114); // R = G = B = pixel; // // pixel = (A << 24) | (R << 16) | (G << 8) | B; // pixels[row + j] = pixel; // } // } // Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Config.ARGB_8888); // bmpGrayscale.setPixels(pixels, 0, width, 0, 0, width, height); // return bmpGrayscale; // } /** * 取灰度图像函数2 * @param bmpOriginal * @return */ public static Bitmap toGray2(Bitmap bmpOriginal) { int width, height; height = bmpOriginal.getHeight(); width = bmpOriginal.getWidth(); Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Canvas c = new Canvas(bmpGrayscale); Paint paint = new Paint(); ColorMatrix cm = new ColorMatrix(); cm.setSaturation(0); ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm); paint.setColorFilter(f); c.drawBitmap(bmpOriginal, 0, 0, paint); return bmpGrayscale; } /** * 取反色 * @param bmpOriginal * @return */ public static Bitmap toInverse(Bitmap bmpOriginal){ int width = bmpOriginal.getWidth(); //获取位图的宽 int height = bmpOriginal.getHeight(); //获取位图的高 int[] pixels = new int[width*height]; //通过位图的大小创建像素点数组 bmpOriginal.getPixels(pixels, 0, width, 0, 0, width, height); int alpha = (byte)((pixels[0] & 0xFF000000)>>24); for(int i = 0; i < height; i++){ for(int j = 0; j < width; j++){ int pixel_src = pixels[width * i + j]; int red = ((pixel_src & 0x00FF0000 ) >> 16); int green = ((pixel_src & 0x0000FF00) >> 8); int blue = (pixel_src & 0x000000FF); red = 255 - red; green = 255 - green; blue = 255 - blue; pixel_src = (alpha<<24) | (red << 16) | (green << 8) | blue; pixels[width * i + j] = pixel_src; } } Bitmap bmpInverse = Bitmap.createBitmap(width, height, Config.ARGB_8888); bmpInverse.setPixels(pixels, 0, width, 0, 0, width, height); return bmpInverse; // bmpOriginal.setPixels(pixels, 0, width, 0, 0, width, height); // return bmpOriginal; }
我的文章首发于公众号
互联网学术(IT-paper)
了解更多,互请扫码上车
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories