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