实现美图秀秀必备的轻量级 Android 滤镜库

3,623 阅读6分钟

gif_sample

本类库可以对ImageView,View Background,Drawable和Bitmap添加风格与设置亮度、对比度。本类库现提供十种风格,具体见下方图示。可以开启动画效果,并设置差值器Interpolator,监听器Listener。对ImageView/View/Drawable可以获取变换风格后的Bitmap。

如果只需要操作ImageView,则可以使用StyleImageView类,该类支持通过布局文件设置属性。如果已经使用了自定义ImageView,或需要操作View的Background,或是任意Drawable与Bitmap,则可以使用Styler类。

注:本类库使用ColorFilter实现效果,如果你已经使用了ColorFilter,有可能产生冲突。

Try Sample

欢迎访问 chengdazhi.com/styleimagev… 下载样例程序apk或者扫描下方二维码:

qr

在样例项目中,style_image_view_test module展示了如何通过xml与java操作StyleImageView。 styler_test module展示了如何使用Styler操作一个ImageView。Styler对于View和Drawable的操作类似。有关如何使用Styler操作Bitmap请查看下文使用说明。

Feature

StyleImageView支持如下10种风格,但对比度(Saturation)风格的图片没有给出,因为需要一个输入值。注意你可以在这些风格之上添加亮度和对比度。

风格模式 海滩 房子与船
Original 无风格 sea_original boat_original
Grey Scale 灰度 sea_grey_scale boat_grey_scale
Invert 反转 sea_invert boat_invert
RGB to BGR RB通道反转 sea_rgb_to_bgr boat_rgb_to_bgr
Sepia 老照片 sea_sepia boat_sepia
Black & White 纯黑白 sea_black_and_white boat_black_and_white
Bright 明亮 sea_bright boat_bright
Vintage Pinhole 针孔 sea_vintage_pinhole boat_vintage_pinhole
Kodachrome 柯达 sea_kodachrome boat_kodachrome
Technicolor 染印 sea_technicolor boat_technicolor

推荐一些组合:

  • Invert 反转 + (150 亮度) + (2.0F 对比度)
  • Sepia 老照片 + (-100 亮度) + (2.0F 对比度)
  • Kodachrome 柯达 + (-75 亮度) + (1.6F 对比度)

可以从示例程序中找到你想要的组合!

使用方式

重要属性

  • Mode 风格模式:你想要实现的风格,包含如下选项:

    1. Saturation 对比度模式
    2. Grey Scale 灰度模式,即常见的黑白照片
    3. Invert 色彩反转
    4. RGB To BGR 将Red与Blue两个颜色通道反转,可理解为另一种色彩翻转
    5. Sepia 老照片
    6. Black And White 硬像,纯黑白,没有灰色
    7. Bright 明亮
    8. Vintage Pinhole 针孔
    9. Kodachrome 柯达
    10. Technicolor 染印
    11. None 无风格,为Mode属性默认值
  • Brightness 亮度:int型,范围[-255,255],取0时没有效果,默认值为0。

  • Contrast 对比度:float型,范围[0, +∞),取1.0时没有效果,默认值1.0。
  • Saturation 饱和度:float型,范围[0, +∞),取1.0时没有效果,默认值1.0。
  • EnableAnimation:是否开启动画,开启时必须给出动画时长(AnimationDuration),可选择给出差值器(Interpolator)。
  • AnimationDuration:动画时长,当关闭动画时会自动重置时长为0。默认值0。

注意:Saturation(饱和度)是单独的一种模式,不可作用于其他模式之上。调用setSaturation()会自动将模式更改。如果在xml中设置了Saturation,而又设置了Mode且不是saturation,就会报错。

库中许多方法提供了文档注释,必要时请参考源码。

StyleImageView使用方式

xml属性

  • style: 枚举类型,默认值为none。
  • brightness:int 整形,默认值为0。
  • contrast:float 浮点型,默认值为1.0。
  • saturation:float 浮点型,默认值为1.0。
  • enable_animation:boolean 布尔型,默认值为false。
  • animation_duration:int 整形(在java中转换为long类型),默认值为0。

注意:如果设置了animation_duration,enable_animation必须设为true,不然会报错。

Java代码

//简单示例
StyleImageView styleImageView = (StyleImageView) this.findViewById(R.id.image);
styleImageView.setMode(Styler.Mode.SEPIA)
        .setBrightness(50)
        .setContrast(0.8)
        .enableAnimation(500L, new LinearInterpolator()) //第一个参数是动画时长,第二个差值器可选
        .setAnimationLisnter(listener) //设置动画监听器,类型为Styler.AnimationListener
        .updateStyle(); //调用updateStyle()更新UI
//updateStyle()之前调用的set方法不区分顺序。

/* getters */
styleImageView.getMode();
styleImageView.getBrightess();
styleImageView.getContrast();
styleImageView.getSaturation();
styleImageView.isAnimationEnabled();
styleImageView.getAnimationDuration();

//获取当前Bitmap,可以指定长宽,否则使用drawable或view的尺寸。
styleImageView.getBitmap([int width, int height]); 

/* setters */
//设置风格,如果参数不是Styler.Mode.SATURATION,但之前设置了saturation,则saturation会被重置为1.0
styleImageView.setMode(int Style.Mode.*);
styleImageView.setBrightness(int brightness);
styleImageView.setContrast(float contrast);

//调用本方法会自动将风格设置为SATURATION
styleImageView.setSaturation(float saturation);

//必须传入时长,可选传入差值器。
//当设置新的时长时也需要调用本方法。
styleImageView.enableAnimation(long duration[, Interpolator interpolator]); 

//关闭动画。会自动重置动画时长和差值器。
styleImageView.disableAnimation(); 

styleImageView.updateStyle(); //更新UI

//清除所有效果,重置Mode为NONE,重置saturation为1.0,不会重置其他属性。
styleImageView.clearStyle();

//给动画设置监听器。如果动画处于关闭状态,监听器方法不会执行。
//监听器会在动画开始、更新与结束时收到回调。
//如果之前设置了监听器,调用本方法会清除原先的监听器。
styleImageView.setAnimationListener(Styler.AnimationListener listener);

//清除AnimationListener并将其返回
styleImageView.removeAnimationListener();

Styler使用方式

Styler可以操作ImageView、View、Drawable和Bitmap。对于前三者Styler最终都是在操作Drawable,一旦Styler被构造,就不能再改变操作的对象了。Styler对Bitmap只提供两个静态方法来设置风格。

简单样例

ImageView imageView = findViewById(R.id.image);
Styler styler = new Styler.Builder(imageView, Styler.Mode.TECHNICOLOR)
        .enableAnimation(1000L)
        .build();

styler.updateUI(); //将图片更新为Technicolor

//重新设置风格、亮度并更新UI。
styler.setMode(Styler.Mode.BLACK_AND_WHITE).setBrightness(100).updateUI(); 

初始化

Styler没有公有的构造方法,你需要使用Styler.Builder类来构建Styler对象。

简单样例

ImageView imageView = (ImageView) this.findViewById(R.id.image);
Styler styler = new Styler.Builder(imageView, Styler.Mode.SEPIA)
        .enableAnimation(500L)
        .setContrast(1.5F)
        .build();

Styler.Builder方法:

//Styler.Builder构造方法,你可以传入ImageViews/Views/Drawables
//如需知道Styler具体工作机制请参考源代码
//注意在Builder中不能再次设置构造方法中的两个参数
Styler.Builder builder = new Styler.Builder(View|ImageView|Drawable, mode);

//setters
//开启动画,必须传入动画时长,可选传入差值器
builder.enableAnimation(long animationDuration[, Interpolator interpolator]);

//关闭动画,自动重置时长为0,差值器为null
builder.disableAnimation();

builder.setBrightness(int brightness);
builder.setContrast(float contrast);

//调用本方法时会自动将模式设为SATURATION
builder.setSaturation(float saturation);

//设置动画监听器。如果动画没有开启,则不会触发监听器的回调。
//监听器会在动画开始、更新与结束时收到回调。
//如果之前设置了监听器,调用本方法会清除原先的监听器。
builder.setAnimationListener(Styler.AnimationListener listener);

//构造Styler对象。
builder.build();

Styler methods

Styler方法包含上文列举的StyleImageView的所有方法,以及下面几个操作Bitmap与获取Drawable的方法。

//返回styler当前正在操作的drawable对象
styler.getDrawable();

//Styler静态方法,对Bitmap快速添加风格
//brightness, contrast, saturation为可选参数,具体参考上文的默认值
//如果mode不是Saturation,而saturation不是1.0,因为saturation为单独的模式,有冲突,会报错
Styler.addStyleToBitmap(Context context, Bitmap bitmap, int mode[, int brightness, float contrast, float saturation]);

Styler.AnimationListener

//三个回调方法:
onAnimationStart();//动画开始时触发

//动画更新时触发,timeFraction指时间上动画进行程度,而progress指动画实际进度。
//当没有通过enableAnimation()方法设置Interpolator或是设置了LinearInterpolator时,timeFraction和progress是一样的。
//progress是Interpolator根据timeFraction计算出的结果。
onAnimationUpdate(float timeFraction, float progress);

onAnimationEnd();//动画结束时触发