Fresco是Facebook发布的一款开源框架,号称是目前最强的Android图片加载库,在内存方面的表现极为优秀,对于Fresco的一些介绍,就不多说了,如果你感兴趣肯定会到网上找一些相关的资料,建议你到中文官网查看:https://www.fresco-cn.org/docs/index.html。好了,话不多说,我这次带给大家的是对于同一个图片如何使用Fresco加载出不同的形状。比如这样的:
实现的原理很简单,就是通过继承BasePostprocessor对图片做一些修改。不熟悉的同学可以去这里瞅瞅https://www.fresco-cn.org/docs/modifying-image.html。
abstract class DrawablePostprocessor : BasePostprocessor() {
var paint: Paint? = null
var drawable: Drawable? = null
init {
paint = Paint()
paint!!.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
}
override fun process(destBitmap: Bitmap?, sourceBitmap: Bitmap?) {
drawable = createDrawable(sourceBitmap!!.width.toFloat(), sourceBitmap!!.height.toFloat())
var bitmap: Bitmap = Bitmap.createBitmap(sourceBitmap!!.width, sourceBitmap!!.height, Bitmap.Config.ARGB_8888)
var canvas: Canvas = Canvas(bitmap)
drawable!!.bounds.set(0, 0, sourceBitmap!!.width, sourceBitmap!!.height)
drawable!!.draw(canvas)
canvas.drawBitmap(sourceBitmap, 0f, 0f, paint)
super.process(destBitmap, bitmap)
}
abstract fun createDrawable(width: Float, height: Float): Drawable
}
在activity中通过fresco加载网络图片。
通过创建ImageRequest 的方式加载图片,在创建ImageRequest 的过程中设置它的Postprocessor,这时我们使用上面的写好的DrawablePostprocessor 创建一个匿名的Postprocessor,同时重写它的createDrawable方法。
class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//图片地址
var url: String = "https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy" +
"/it/u=3276424759,4034967609&fm=26&gp=0.jpg"
var imageRequest: ImageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(url!!))
.setPostprocessor(object : DrawablePostprocessor() {
override fun createDrawable(width: Float, height: Float): Drawable {
//五角星
return FivePointedStarDrawable(width, height)
//菱形
//return DiamondDrawable(width, height)
//半圆
//return HalfCircleDrawable(width, height)
//平行四边形
//return ParallelogramDrawable(width, height)
}
}).build()
var controller: DraweeController = Fresco.newDraweeControllerBuilder().setImageRequest(imageRequest)
.setOldController(iv_image.controller).build()
iv_image.controller = controller
iv_image_origin.setImageURI(Uri.parse(url))
}
}
ShapeDrawable 父类
abstract class ShapeDrawable constructor(width: Float, height: Float) : Drawable() {
var paint: Paint? = null
var width: Float = 0F
var height: Float = 0F
init {
this.width = width
this.height = height
paint = Paint()
}
override fun setAlpha(alpha: Int) {
paint?.alpha = alpha
}
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
override fun setColorFilter(colorFilter: ColorFilter?) {
paint?.colorFilter = colorFilter
}
override fun getIntrinsicWidth(): Int {
return width.toInt()
}
override fun getIntrinsicHeight(): Int {
return height.toInt()
}
}
具体实现子类
class FivePointedStarDrawable constructor(width: Float, height: Float) : ShapeDrawable(width, height) {
init {
super.width = width
super.height = height
}
//绘制五角星
override fun draw(canvas: Canvas?) {
val path = Path()
var radius = Math.min(width, height) / 2
val radian = degree2Radian(36)// 36为五角星的角度
val radius_in = (radius * Math.sin((radian / 2).toDouble()) / Math
.cos(radian.toDouble())).toFloat() // 中间五边形的半径
path.moveTo((radius * Math.cos((radian / 2).toDouble())).toFloat(), 0F)// 此点为多边形的起点
path.lineTo((radius * Math.cos((radian / 2).toDouble()) + radius_in * Math.sin(radian.toDouble())).toFloat(),
(radius - radius * Math.sin((radian / 2).toDouble())).toFloat())
path.lineTo((radius.toDouble() * Math.cos((radian / 2).toDouble()) * 2.0).toFloat(),
(radius - radius * Math.sin((radian / 2).toDouble())).toFloat())
path.lineTo((radius * Math.cos((radian / 2).toDouble()) + radius_in * Math.cos((radian / 2).toDouble())).toFloat(),
(radius + radius_in * Math.sin((radian / 2).toDouble())).toFloat())
path.lineTo(
(radius * Math.cos((radian / 2).toDouble()) + radius * Math.sin(radian.toDouble())).toFloat(), (radius + radius * Math.cos(radian.toDouble())).toFloat())
path.lineTo((radius * Math.cos((radian / 2).toDouble())).toFloat(),
(radius + radius_in).toFloat())
path.lineTo(
(radius * Math.cos((radian / 2).toDouble()) - radius * Math.sin(radian.toDouble())).toFloat(), (radius + radius * Math.cos(radian.toDouble())).toFloat())
path.lineTo((radius * Math.cos((radian / 2).toDouble()) - radius_in * Math.cos((radian / 2).toDouble())).toFloat(),
(radius + radius_in * Math.sin((radian / 2).toDouble())).toFloat())
path.lineTo(0F, (radius - radius * Math.sin((radian / 2).toDouble())).toFloat())
path.lineTo((radius * Math.cos((radian / 2).toDouble()) - radius_in * Math.sin(radian.toDouble())).toFloat(),
(radius - radius * Math.sin((radian / 2).toDouble())).toFloat())
path.close()// 使这些点构成封闭的多边形
canvas!!.drawPath(path, paint)
}
fun degree2Radian(degree: Int): Float {
return (Math.PI * degree / 180).toFloat()
}
}
本篇博客的目的呢,就是为了简绍Fresco的BasePostprocessor,在此分享出来希望和大家共同学习,共同进步,如文中有什么问题,或者kotlin的使用有误的地方,希望提出,本人不胜感激。如有疑问可以联系我邮箱[email protected]。
源码下载