滑动如何创建具有弯曲边缘的自定义变换

时间:2018-02-17 11:48:30

标签: android canvas graphics transformation android-glide

我正在尝试创建自定义转换。我的想法是创建一个弯曲边缘不是完全圆形的正方形,与CircleCrop不同。

希望下面的图片能让您了解我想要绘制的内容:

enter image description here

上图有两个带位图的样本,另一个带有占位符可绘制的样本。

我尝试使用现有的RoundEdgesTransformation创建CircleTransformation。我尝试通过弧形绘制画布,圆形矩形但没有得到适当的结果,因为我没有专注于大学的计算机图形学。

这是我现有的代码:

class RoundEdgesTransformation : BitmapTransformation() {

    private val VERSION = 1
    private val ID = "com.app.messia.custom_view.RoundEdgesTransformation" + VERSION
    private val ID_BYTES = ID.toByteArray(Key.CHARSET)

    companion object {
        val DEFAULT_PAINT_FLAGS = Paint.DITHER_FLAG or Paint.FILTER_BITMAP_FLAG or Paint.ANTI_ALIAS_FLAG
        val DEFAULT_CANVAS_PAINT = Paint(DEFAULT_PAINT_FLAGS)
    }

    @Suppress("PrivatePropertyName")
    private val DEFAULT_BITMAP_PAINT: Paint

//    private val paint1: Paint = Paint()
//    private val paint2: Paint = Paint()
//    private val paint3: Paint = Paint()
//    private val paint4: Paint = Paint()

    init {
//        DEFAULT_CANVAS_PAINT.color = Color.GREEN

//        paint1.color = Color.RED
//        paint2.color = Color.GREEN
//        paint3.color = Color.BLUE
//        paint4.color = Color.MAGENTA

        DEFAULT_BITMAP_PAINT = Paint(DEFAULT_PAINT_FLAGS)
        DEFAULT_BITMAP_PAINT.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    }


    override fun transform(pool: BitmapPool, inBitmap: Bitmap, destWidth: Int, destHeight: Int): Bitmap {
        val destMinEdge = Math.min(destWidth, destHeight)
        val radius = destMinEdge / 2f

        val srcWidth = inBitmap.width
        val srcHeight = inBitmap.height

        val scaleX = destMinEdge / srcWidth.toFloat()
        val scaleY = destMinEdge / srcHeight.toFloat()
        val maxScale = Math.max(scaleX, scaleY)

        val scaledWidth = maxScale * srcWidth
        val scaledHeight = maxScale * srcHeight
        val left = (destMinEdge - scaledWidth) / 2f
        val top = (destMinEdge - scaledHeight) / 2f

        val destRect = RectF(left, top, left + scaledWidth, top + scaledHeight)

        // Alpha is required for this transformation.
        val toTransform = getAlphaSafeBitmap(pool, inBitmap)

        val result = pool.get(destMinEdge, destMinEdge, Bitmap.Config.ARGB_8888)
        result.setHasAlpha(true)

//        BITMAP_DRAWABLE_LOCK.lock()
        try {
            val canvas = Canvas(result)
            // Draw a circle
//            canvas.drawCircle(radius, radius, radius, DEFAULT_CANVAS_PAINT)
//            canvas.drawRect(destRect, DEFAULT_CANVAS_PAINT)

            canvas.drawArc(destRect, -45F, 90F, true, DEFAULT_CANVAS_PAINT)
            canvas.drawArc(destRect, 45F, 90F, true, DEFAULT_CANVAS_PAINT)
            canvas.drawArc(destRect, 135F, 90F, true, DEFAULT_CANVAS_PAINT)
            canvas.drawArc(destRect, 225F, 90F, true, DEFAULT_CANVAS_PAINT)

//            canvas.drawRoundRect(destRect, radius / 2, radius, DEFAULT_CANVAS_PAINT)
            // Draw the bitmap in the circle
            // it has got SRC_IN mode
            canvas.drawBitmap(toTransform, null, destRect, DEFAULT_BITMAP_PAINT)
            clear(canvas)
        } finally {
//            BITMAP_DRAWABLE_LOCK.unlock()
        }

        if (toTransform != inBitmap) {
            pool.put(toTransform)
        }

        return result
    }

    private fun getAlphaSafeBitmap(pool: BitmapPool, bitmap: Bitmap): Bitmap {
        if (Bitmap.Config.ARGB_8888 == bitmap.config) return bitmap

        val argbBitmap = pool.get(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
        Canvas(argbBitmap).drawBitmap(bitmap, 0f /*left*/, 0f /*top*/, null /*paint*/)

        // We now own this Bitmap. It's our responsibility to replace it in the pool outside this method
        // when we're finished with it.
        return argbBitmap
    }

    // Avoids warnings in M+.
    private fun clear(canvas: Canvas) {
        canvas.setBitmap(null)
    }

    override fun equals(other: Any?): Boolean {
        return other is RoundEdgesTransformation
    }

    override fun hashCode(): Int {
        return ID.hashCode()
    }

    override fun updateDiskCacheKey(messageDigest: MessageDigest) {
        messageDigest.update(ID_BYTES)
    }

}

如果有人建议我有可能实现它,我会很棒。

0 个答案:

没有答案