I'm trying to load in an imageview an image returned from the camera of the device and gett the colors of the pixel I touch.
I tried scaling the image in the xml file, but when I do although I see the image fit in the imageview the touchlistener works at the original dimensions of the image. If I don't scale it I see only the part of the image that fits the imageview and the touchlistener get the actual pixel.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath)
ivCamera.setImageBitmap(bitmap)
ivCamera.setOnTouchListener { view, motionEvent ->
val bmp = (ivCamera.drawable as BitmapDrawable).bitmap
val pixel = bmp.getPixel(motionEvent!!.x.toInt(), motionEvent.y.toInt())
pixelRed = Color.red(pixel)
pixelGreen = Color.green(pixel)
pixelBlue = Color.blue(pixel)
tvColor.setBackgroundColor(Color.rgb(pixelRed!!, pixelGreen!!, pixelBlue!!))
true
}
}
}
<ImageView android:layout_width="match_parent"
android:layout_weight="0.7"
android:layout_height="0dp"
android:id="@+id/ivCamera"
android:scaleType="matrix"
android:background="@android:drawable/ic_menu_report_image"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
app:layout_constraintHorizontal_bias="0.498"
android:layout_margin="10dp"
android:layout_marginBottom="8dp"
android:adjustViewBounds="true"
app:layout_constraintBottom_toBottomOf="parent"
android:contentDescription="PicureTaken"/>
If I scale the image in the xml file, I see the image fitted in the imageview but the touchlistener works at the original dimensions of the image. If I don't scale it I see only the part of the image that fits the imageview and the touchlistener get the actual pixel.
This might be one of those crazy scenarios where you are setting the touch listener ivCamera.setOnTouchListener
before the XML scale type has took effect ivCamera.setImageBitmap
. i.e. it sets a touch on the original dimensions before the scaleType
comes into effect.
You could use a layout listener to set the touch listener after the ImageView has finished inflating.
https://developer.android.com/reference/android/view/ViewTreeObserver.OnGlobalLayoutListener
ivCamera.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ivCamera.getViewTreeObserver().removeOnGlobalLayoutListener(this);
if(ivCamera.getDrawable() != null) {
ivCamera.setOnTouchListener {
// etc
// ...
}
}
});
This isn't an answer I am confident in, but an answer. :-) sorry it's so horrible / such a hack!
Looking at this again...
val bmp = (ivCamera.drawable as BitmapDrawable).bitmap
val pixel = bmp.getPixel(motionEvent!!.x.toInt(), motionEvent.y.toInt())
You get the bitmap back off of the ImageView, then call getPixel
however clearly .bitmap
is returning you the original sized bitmap even though you scaled it (for the view) with scaleType
.
My recommendation would either be to translate the x/y co-ordinates of the touch event to the scaled image size.
Or scale the bitmap yourself before you call setImageBitmap
on the ImageView. That way you don't need to translate the x/y.