@@ -5,6 +5,7 @@ import android.graphics.Bitmap
55import android.graphics.Paint
66import android.graphics.PorterDuff
77import android.graphics.PorterDuffXfermode
8+ import android.graphics.RectF
89import android.graphics.drawable.Drawable
910import androidx.annotation.DrawableRes
1011import androidx.core.content.res.ResourcesCompat
@@ -13,43 +14,41 @@ import androidx.core.graphics.createBitmap
1314import coil.size.Size
1415import coil.transform.Transformation
1516import com.commit451.coiltransformations.Util.safeConfig
17+ import kotlin.math.max
1618
1719/* *
1820 * Mask transformation using another drawable.
1921 * @param context context for loading the drawable
2022 * @param maskDrawableRes the drawable resource to use as the mask
2123 */
22- class MaskTransformation (
23- private val context : Context ,
24- @DrawableRes val maskDrawableRes : Int
25- ) : Transformation {
24+ class MaskTransformation (private val context : Context , @DrawableRes val maskDrawableRes : Int ) : Transformation {
2625
2726 companion object {
28- private val paint = Paint ()
29- .apply {
30- xfermode = PorterDuffXfermode (PorterDuff .Mode .SRC_IN )
31- }
27+ private val paint = Paint (Paint .ANTI_ALIAS_FLAG or Paint .FILTER_BITMAP_FLAG ).apply {
28+ xfermode = PorterDuffXfermode (PorterDuff .Mode .SRC_IN )
29+ }
3230 }
3331
3432 override val cacheKey: String = " ${MaskTransformation ::class .java.name} -$maskDrawableRes "
3533
36- override suspend fun transform (input : Bitmap , size : Size ): Bitmap {
37-
38- val output = createBitmap(input.width, input.height, input.safeConfig)
39- output.setHasAlpha(true )
40-
41- val mask = getMaskDrawable(context.applicationContext, maskDrawableRes)
42-
43- output.applyCanvas {
44- mask.setBounds(0 , 0 , width, height)
45- mask.draw(this )
46- drawBitmap(input, 0f , 0f , paint)
34+ override suspend fun transform (input : Bitmap , size : Size ) = getMaskDrawable(context, maskDrawableRes).let {
35+ it.setBounds(0 , 0 , it.intrinsicWidth, it.intrinsicHeight)
36+ createBitmap(it.intrinsicWidth, it.intrinsicHeight, input.safeConfig).applyCanvas {
37+ it.draw(this )
38+ val scale = max(it.intrinsicWidth.toFloat() / input.width, it.intrinsicHeight.toFloat() / input.height)
39+ val scaledWidth = scale * input.width
40+ val scaledHeight = scale * input.height
41+ val left = (it.intrinsicWidth - scaledWidth) / 2
42+ val top = (it.intrinsicHeight - scaledHeight) / 2
43+ drawBitmap(input, null , RectF (left, top, left + scaledWidth, top + scaledHeight), paint)
4744 }
48- return output
4945 }
5046
5147 private fun getMaskDrawable (context : Context , maskId : Int ): Drawable {
5248 return ResourcesCompat .getDrawable(context.resources, maskId, null )
5349 ? : throw IllegalArgumentException (" maskId is invalid" )
5450 }
51+
52+ override fun equals (other : Any? ) = (other as ? MaskTransformation )?.maskDrawableRes == maskDrawableRes
53+ override fun hashCode () = cacheKey.hashCode()
5554}
0 commit comments