带有边框的毕加索图像蒙版转换

时间:2018-11-23 00:32:23

标签: android kotlin android-canvas picasso android-image

我正在尝试使用毕加索Transformation在带有防潮罩的图像上绘制边框。防潮罩是VectorDrawable。

我认为最简单,最灵活的方法是先使用canvas.drawPaint绘制较大的所需边框颜色的线形。然后使用canvas.drawBitmap使用照片位图绘制一个较小的鼠形。我可以分别绘制它们,也可以缩放位图并成功地将其与遮罩一起绘制,但是任何时候我尝试将两者结合在一起,都会在canvas.drawBitmap调用中丢失遮罩。关于我可能做错了什么的任何想法?

我尝试了很多混合模式选项,但我认为这不是问题。

override fun transform(source: Bitmap): Bitmap {
    val width = source.width
    val height = source.height
    val borderWidth = 100

    val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(output)

    //Draw a full size, red squircle
    val paint = Paint()
    paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    paint.color = Color.RED
    val mask = context.getDrawable(maskID)
    mask.setBounds(0, 0, width, height)
    mask.draw(canvas)
    canvas.drawPaint(paint)

    //Draw a masked, scaled down bitmap of the photo on top
    val bitmapPaint = Paint()
    bitmapPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    val bitmapMask = context.getDrawable(maskID)
    bitmapMask.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)
    bitmapMask.draw(canvas)

    val sourceDrawable = source.toDrawable(context.resources)
    sourceDrawable.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)
    canvas.drawBitmap(sourceDrawable.bitmap, null,
           Rect(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2),
           bitmapPaint)

    source.recycle()

    return output
}

结果:

Squircle with unmasked bitmap

如果我注释掉对drawBitmap的呼叫,我会得到以下结果(快到了!):

Squircle with mask only

1 个答案:

答案 0 :(得分:1)

更新27/11/2018

我已经解决了这个问题,方法是在具有所需蒙版的临时画布上绘制图片,然后在主画布上绘制结果位图。源代码和视觉结果包含在此处:

MaskTransformation.kt

import android.content.Context
import android.graphics.*
import android.graphics.drawable.BitmapDrawable
import android.support.annotation.DrawableRes
import android.support.v4.content.ContextCompat
import com.squareup.picasso.Transformation


class MaskTransformation(
    private val context: Context,
    @DrawableRes private val maskID: Int
) : Transformation {

    override fun key(): String {
        return "mask"
    }

    override fun transform(source: Bitmap): Bitmap {
        val width = source.width
        val height = source.height
        val borderWidth = 400

        val output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(output)

        //Draw a full size, red squircle
        val paint = Paint()
        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        paint.color = Color.RED
        val mask = ContextCompat.getDrawable(context, maskID)!!
        mask.setBounds(0, 0, width, height)
        mask.draw(canvas)
        canvas.drawPaint(paint)

        //Draw a masked, scaled down bitmap of the photo on top
        val maskingPaint = Paint()
        maskingPaint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        val maskDrawable = ContextCompat.getDrawable(context, maskID)!!
        maskDrawable.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)

        val overlayBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val overlayCanvas = Canvas(overlayBitmap)
        maskDrawable.draw(overlayCanvas)

        val pictureBitmap = Bitmap.createBitmap(width - borderWidth, height - borderWidth, Bitmap.Config.ARGB_8888)
        val pictureCanvas = Canvas(pictureBitmap)

        val sourceDrawable = BitmapDrawable(context.resources, source)
        sourceDrawable.setBounds(borderWidth / 2, borderWidth / 2, width - borderWidth / 2, height - borderWidth / 2)
        pictureCanvas.drawBitmap(
            sourceDrawable.bitmap,
            null,
            Rect(0, 0, width - borderWidth, height - borderWidth),
            Paint()
        )

        overlayCanvas.drawBitmap(pictureBitmap, (borderWidth / 2).toFloat(), (borderWidth / 2).toFloat(), maskingPaint)

        canvas.drawBitmap(overlayBitmap, 0f, 0f, Paint())

        source.recycle()

        return output
    }

}

MainActivity.kt

import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Picasso.get()
            .load(R.drawable.img_aminography)
            .transform(MaskTransformation(this, R.drawable.ic_squircle))
            .into(imageView)

    }
}

ic_squircle.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="32"
        android:viewportHeight="32">

    <path android:fillColor="#000000"
          android:pathData="M31.2,14.3v3.5c0,9.8,-5.9,13.5,-13.4,13.5h-3.5c-7.7,0,-13.5,-3.4,-13.5,-13.5v-3.5c0,-10.8,6,-13.5,13.5,-13.5h3.5C25.2,0.8,31.2,4.1,31.2,14.3"/>

</vector>

视觉结果

enter image description here