滤镜
滤镜;主要是用来实现图像的各类特殊效果。它在Photoshop中具备很是神奇的做用。滤镜一般须要同通道、图层等联合使用,才能取得最佳艺术效果。java
在移动端或者在web开发时处理图片都是一件麻烦的事儿。我调研过不少library,特别是在移动端处理图片时动不动都须要使用 C++ 或者 OpenCV。这对于 Java 程序员来讲,具备很高的门槛。甚至在调试时,遇到错误都会没法下手进行处理。其实,随着手机设备性能的不断提升,使用 Java 一样能完成这些事情。android
实现
这是原图,能够选择滤镜来美化图片。git

这是几种滤镜的效果程序员

首先,咱们的库叫 cv4j,cv 是 Computer Vision 的意思,同时也用于致敬 OpenCV。
https://github.com/imageprocessor/cv4jgithub
以SepiaTone滤镜为例,咱们本身私下叫它怀旧风格的滤镜web

import com.cv4j.core.datamodel.ImageData; import com.cv4j.image.util.Tools; public class SepiaToneFilter implements CommonFilter { @Override public ImageData filter(ImageData src) { int width = src.getWidth(); int height = src.getHeight(); int offset = 0; for(int row=0; row<height; row++) { offset = row * width; int tr = 0, tg = 0, tb = 0; for (int col = 0; col < width; col++) { tr = (src.getPixels()[offset] >> 16) & 0xff; tg = (src.getPixels()[offset] >> 8) & 0xff; tb = src.getPixels()[offset] & 0xff; int fr = (int) colorBlend(noise(), (tr * 0.393) + (tg * 0.769) + (tb * 0.189), tr); int fg = (int) colorBlend(noise(), (tr * 0.349) + (tg * 0.686) + (tb * 0.168), tg); int fb = (int) colorBlend(noise(), (tr * 0.272) + (tg * 0.534) + (tb * 0.131), tb); src.getPixels()[offset] = (255 << 24) | (Tools.clamp(fr) << 16) | (Tools.clamp(fg) << 8) | Tools.clamp(fb); offset++; } } return src; } private double noise() { return Math.random()*0.5 + 0.5; } private double colorBlend(double scale, double dest, double src) { return (scale * dest + (1.0 - scale) * src); } }
ImageData是咱们本身定义的图像数据结构。全部的滤镜都是经过ImageData来传递。算法
import android.graphics.Bitmap; public interface ImageData { int CV4J_IMAGE_TYPE_RGB = 0; int CV4J_IMAGE_TYPE_GRAY = 2; int CV4J_IMAGE_TYPE_HSV = 4; int CV4J_IMAGE_TYPE_BINARY = 8; int[] getPixels(); int getWidth(); int getHeight(); int getType(); byte[] getChannel(int index); void putPixels(int[] pixels); int getPixel(int row, int col); void setPixel(int row, int col, int rgb); int[] getPixelByRowNumber(int rowIndex); void convert2Gray(); Bitmap toBitmap(); }
ImageData是一个接口,目前它的实现类只有ColorImage。
因此使用一个滤镜,一般只要这样写的就ok了。数据结构
ColorImage colorImage = new ColorImage(bitmap); CommonFilter filter = new SepiaToneFilter(); colorImage = (ColorImage) filter.filter(colorImage); imageView.setImageBitmap(colorImage.toBitmap());
性能是咱们一直关心的话题,我在模拟器上跑了demo app,经过 AOP 的方法打印了 demo app 中一些滤镜在使用时花费的时间。架构

在demo app中,滤镜实例化是借助Class.forName()确定比直接使用new 某个滤镜类要慢一些。app

总结
cv4j 是贾志刚和我一块儿开发的图像处理库,目前还处于很早期的版本。咱们天天都会对这个库作一些提交。整个库在架构上和图像算法上都还有很大的提高空间。
本文同步分享在 博客“fengzhizi715”(JianShu)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。