Android Java代码实现滤镜
目前很多应用实现滤镜的方式都是使用 ndk 开发,如大名鼎鼎的 GPUImage ,但是使用 ndk 的方法就需要为不同的 abi 提供不同的 .so 文件,感觉维护起来比较麻烦,这里就给出一种简单的 Java 版本的滤镜实现.
目前可以找到的改变的值有 亮度, 饱和度, 对比度, 色温, 前三者需要用到 ColorMatrix
这个类, 后面的色温用到 ColorFilter
这个类.
亮度
ColorMatrix lMatrix = new ColorMatrix(); lMatrix.set(new float[]{ 1, 0, 0, 0, light, 0, 1, 0, 0, light, 0, 0, 1, 0, light, 0, 0, 0, 1, 0});
饱和度
ColorMatrix cMatrix = new ColorMatrix(); cMatrix.setSaturation(saturation);
对比度
float contrast; float scale = (contrast / 255f - 0.5f) / -0.5f; ColorMatrix dMatrix = new ColorMatrix(); dMatrix.set(new float[]{ scale, 0, 0, 0, contrast, 0, scale, 0, 0, contrast, 0, 0, scale, 0, contrast, 0, 0, 0, 1, 0});
联合以上三个属性,只需要将三个矩阵连接起来即可.
ColorMatrix finalMatrix = new ColorMatrix();
finalMatrix.postConcat(cMatrix);
finalMatrix.postConcat(lMatrix);
finalMatrix.postConcat(dMatrix);
ImageView.setColorFilter(new ColorMatrixColorFilter(finalMatrix));
色温
色温主要调节冷暖,但是因为没有具体的换算公式,所以我采用查表的方法 色温表. 查表后对
Drawable
对象调用setColorFilter
方法在其上面再覆盖一层颜色.String color = "#818181";//查表得 drawable.setColorFilter(Color.parseColor(color), PorterDuff.Mode.MULTIPLY);
保存 Bitmap
在设置这些属性的时候,都是对 ImageView 或 Drawable 操作, 但如果需要保存, 还是需要 Bitmap 对象.以下代码便是提供保存滤镜 Bitmap 的方法:
.....
ColorMatrix finalMatrix = new ColorMatrix();
finalMatrix.postConcat(cMatrix);
finalMatrix.postConcat(lMatrix);
finalMatrix.postConcat(dMatrix);
....
Bitmap bmp = Bitmap.createBitmap(imageWidth, imageHeight,
Bitmap.Config.ARGB_8888);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(finalMatrix));
Canvas canvas = new Canvas(bmp);
canvas.drawBitmap(mOriginBitmap, 0, 0, paint);
//此时bmp即为所需要保存的Bitmap