0

I have two images - one ("back") that is displayed as a background and another ("stick") that the user drags around. "Back" is displayed with some scalings (match_parent on the image view), so there are actually 3 images in play. I need to apply "stick" to the third (original) image in the exact same position as it is displayed on the "back". I've tried to do it with matrices but had more luck manually calculating the offsets, yet it's still not enough as there are some weird offsets coming up and the "stick" is some pixels to the left. That's not even to say that it does not work if the image is more horizontal. Here's how I calculate it:

val stickerBitmap = stickerView.drawToBitmap().trimBorders(Color.argb(0, 0, 0, 0))
val originalBitmap = fa
var purePageView = pageView.drawToBitmap()
val displayedBitmap = pageView.drawToBitmap().trimBorders(Color.argb(0, 0, 0, 0))
var (h1, w1) = stickerView.bounds
w1 -= binding.toolbar.height + binding.pageView.marginTop
h1 -= (binding.pageView.marginStart + binding.pageView.marginEnd + (purePageView.width - displayedBitmap.width)/2)
val x = originalBitmap.height
val y = originalBitmap.width
val x1 = displayedBitmap.height
val y1 = displayedBitmap.width
val x2 = stickerBitmap.height
val y2 = stickerBitmap.width
val h = h1 * y / y1.toFloat()
val w = x * w1 / x1.toFloat()
val x3 = x2 * x / x1
val y3 = y2 * y / y1
val scaledSticker2 = Bitmap.createScaledBitmap(stickerBitmap, y3, x3, true)
val resultBitmap = Bitmap.createBitmap(
    originalBitmap.width,
    originalBitmap.height,
    Bitmap.Config.ARGB_8888
)
val resultCanvas = Canvas(resultBitmap)
val paint = Paint()
var cf = PorterDuffColorFilter(Color.argb(255,0,255,0), PorterDuff.Mode.SRC_IN)
paint.colorFilter = cf
resultCanvas.drawBitmap(originalBitmap, 0f, 0f, null)

cf = PorterDuffColorFilter(Color.argb(255,0,255,255), PorterDuff.Mode.SRC_IN)
paint.colorFilter = cf
resultCanvas.drawBitmap(scaledSticker2, h + binding.pageView.marginStart, w+abs(binding.pageView.marginTop-binding.pageView.marginBottom), paint)

cf = PorterDuffColorFilter(Color.argb(255,0,123,123), PorterDuff.Mode.SRC_IN)
paint.colorFilter = cf
resultCanvas.drawBitmap(scaledSticker2, h + binding.pageView.marginStart, w+abs(binding.pageView.marginTop-binding.pageView.marginBottom), paint)

Code for trimBorders from here. What may be missing? Is there a different way altogether?

Bijin Abraham
  • 1,709
  • 2
  • 11
  • 25
Dan
  • 1
  • 1

1 Answers1

0

In the end, what was required is to subtract any additional space between the image view and parent view as well as additional space inside the image view between the view and the image. I modified trimBitmap to also return found image top and left cords, and scaled the result of subtraction.

val originalBitmap = BitmapFactory.decodeFile(
    File(
        context.filesDir,
        originalName
    ).path,
    BitmapFactory.Options().apply { inPreferredConfig = Bitmap.Config.ARGB_8888 })
val swb = IntArray(2)
val stickerBitmap = stickerView.drawToBitmap().trimBorders(Color.argb(0, 0, 0, 0), swb)
val displayedBitmap = pageView.drawToBitmap().trimBorders(Color.argb(0, 0, 0, 0))
val (w1, h1) = swb
val wB = (pageView.width - displayedBitmap.width) / 2
val hB = (pageView.height - displayedBitmap.height) / 2
val x = originalBitmap.height
val y = originalBitmap.width
val x1 = displayedBitmap.height
val y1 = displayedBitmap.width
val x2 = stickerBitmap.height
val y2 = stickerBitmap.width
val h = (h1 - (toolbar.height + pageView.marginTop + hB)) * y / y1.toFloat()
val w = x * (w1 - (wB + pageView.marginStart)) / x1.toFloat()
val x3 = x2 * x / x1
val y3 = y2 * y / y1
val scaledSticker2 = Bitmap.createScaledBitmap(stickerBitmap, y3, x3, true)
val resultBitmap = Bitmap.createBitmap(
    originalBitmap.width,
    originalBitmap.height,
    Bitmap.Config.ARGB_8888
)
val resultCanvas = Canvas(resultBitmap)

resultCanvas.drawBitmap(originalBitmap, 0f, 0f, null)
resultCanvas.drawBitmap(scaledSticker2, w, h, null)
Dan
  • 1
  • 1