How to get colour of touched area in canvas - Android - android

I have created a custom view inside which I have drawn multiple arcs of different colors.
On touching how can I get the color of the touched point?

In Java:
final Bitmap bitmap = Bitmap.createBitmap(customView.getWidth(), customView.getHeight(), Bitmap.Config.ARGB_8888);
customView.draw(new Canvas(bitmap));
customView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int color = bitmap.getPixel((int) event.getX(), (int) event.getY());
return true;
}
});
In Kotlin:
val bitmap = Bitmap.createBitmap(customView.getWidth(), customView.getHeight(), Bitmap.Config.ARGB_8888)
customView.draw(Canvas(bitmap))
customView.setOnTouchListener(View.OnTouchListener { _, event ->
val color = bitmap.getPixel(event.x.toInt(), event.y.toInt())
true
})

Solution to above has two step's
Step 1: Getting the bitmap for your View as canvas is nothing more than a container which holds drawing calls to manipulate a bitmap.As view can update itself based on user event's or some other case then bitmap need's to be updated on onDraw call.
refer here how to do it.
Step 2: And once you get hold of bitmap get the x and y position from event of view
and get specific color of pixel.
refer here how to do it.

Ref :: Bitmap
getPixel(int x, int y)
Returns the Color at the specified location.
Ex
<!--Java-->
int color = bitmapObject.getPixel(10, 10);
<!--Kotlin-->
val color = bitmap.getPixel(10, 10)

Related

Android get Position of Bitmap in ImageView

I am using CropView which extends an Android ImageView. It allows the image with in the the view to be scaled and moved around. there does not appear to be any public reference to the image position or scale. Is there a way to get the position of an image relative to a regular ImageView that I can try.
I have also tried setting a touch listener on the CropView that simply prints the x & y positions of the touch but i don see how i can use these to move get the updated position of the image.
mCropView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "///" + event.getX() + " __ " + event.getY());
return false;
}
});
https://github.com/lyft/scissors/blob/master/scissors/src/main/java/com/lyft/android/scissors/CropView.java
The CropView itself is the viewport. Cropview has two methods getViewportWidth
and getViewportHeight. You'll need them.
The image that is scaled, moved, cropped etc is a Drawable. Drawable has a getBounds method that will return a Rect. You can get the top, left width and height from this Rect but you need to get the Drawable first.
CropView calls this Drawable "bitmap". You can get it calling the CropView's getImageBitmap() method.
Once you have it, call getBounds which gives you the image's Rect.
To get the x and y you want you'll have to do a bit of math with the Rect's top, left, width and height along with the viewport's height and width which you'll get from CropView's getViewportHeight and getViewportWidth methods.
Simply:
vpwidth=cropview.getViewPortWidth();
vpheight=cropview.getViewPortHeight();
imagetop=cropview.getImageBitmap().getBounds().top;
imageleft=cropview.getImageBitmap().getBounds().left;
imageheight=cropview.getImageBitmap().getBounds().height;
imagewidth=cropview.getImageBitmap().getBounds().width;
>math here
You could try out the method below,
final float[] getPointOfTouchedCordinate(ImageView view, MotionEvent e) {
final int index = e.getActionIndex();
final float[] coords = new float[] { e.getX(index), e.getY(index) };
Matrix m = new Matrix();
view.getImageMatrix().invert(m);
m.postTranslate(view.getScrollX(), view.getScrollY());
m.mapPoints(coords);
return coords;
}
you can get the value
mCropView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
float[] points = getPointOfTouchedCordinate(v, event);
Log.d(TAG, "///" + points[0] + " __ " + points(1));
return false;
}
});
I suggest to rely on pure xml and add to the Imagevie:
android:scaleType="centerCrop"
this will lead to the desired output as drawn.

How to take real coordinates(X,Y) of Bitmap from imageView Android

i have little problem.
I'm getting an image,converting to Bitmap and fill imageview with this Bitmap.
So the problem is,how to take real coordinates(X,Y) of this Bitmap?
For better illustration, i attached an image:
As shown on picture, for e.g. i got an image with Custom Resolution,where user can make an perspective , via yellow points.
So i need to know,how to take real coords of bitmap from ImageView.
What i've made at current moment(but this approach isn't correct):
i take width/height from imageView and recreating new bitmap with this resolution.
Bitmap bt = Bitmap.CreateScaledBitmap(BitmapFactory.DecodeResource(Activity.Resources, Resource.Drawable.test),800,1420,false); //800 width 1420 height
imgView.SetImageBitmap(bt);
Via implementation of TouchListener(methods GetX()/GetY()),i get coords of points(yellow circle's that overlayed on Bitmap), and the problem is that these coordinates not correct.
Also its interesting for me case when i'm stretching bitmap via ScaleType.FitXY on imageView(its possible to take real coords of bitmap) ?
So how can i achieve my goal?
use ImageView#getImageMatrix, something like this:
final ImageView iv = new ImageView(this);
setContentView(iv);
// setup your image here by
// calling for example iv.setImageBitmap()
// or iv.setImageDrawable()
// or iv.setImageResource()
View.OnTouchListener otl = new View.OnTouchListener() {
Matrix inverse = new Matrix();
#Override
public boolean onTouch(View v, MotionEvent event) {
iv.getImageMatrix().invert(inverse);
float[] pts = {
event.getX(), event.getY()
};
inverse.mapPoints(pts);
Log.d(TAG, "onTouch x: " + Math.floor(pts[0]) + ", y: " + Math.floor(pts[1]));
return false;
}
};
iv.setOnTouchListener(otl);

Selected pixel of displayed image?

I am selecting some area of image in displayed imageview. Then i do some work on selected pixels of that bitmap which is displayed in imageview. But i am not able to hit those pixel which user selected. I know i have to do some pixel mapping of displayed image and actual bitmap. See images for better understanding of my problem.
User select some pixel using circular selector
After processing affected pixels are different not those which user selected
I have tried some thing like this to get accurate pixels
Bitmap image = EyeColorChangerActivity.getImageBitmap();
int displayedwidht = image.getWidth();
int displayedheight = image.getHeight();
x = x*((float)displayedwidht/mScreenWidth);
y = y*((float)displayedheight/mScreenHeight);
Set OnTouchListener on your ImageView.
Inside onTouch method of OnTouchListener use the following code to get the selected bitmap pixel.
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
int x = (int) arg1.getX();
int y = (int)arg1.getY();
int pixel = mBitmap.getPixel(x, y);
// process new color for selected pixel.
....
//set new color to bitmap pixel
return false;
}

android: place image on display based on where user touches (api 11+)

Hello I am trying to place an imageview on an area where the user touches.
using MotionEvent event
Simply doing imageview.setX(event.getX()) and imageview.setY(event.getY()) is not the complete solution.
I realize these are pixel values, so I tried converting the event values to density independent values using (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, event.getX() , getResources()
.getDisplayMetrics());
but this still does not give me coordinates that match where I touch, when I try to show the imageview at this location.
Also, I am under the suspicion that the imageview draws its upper left corner at these coordinates, when I want the coordinates to be the at center of the imageview.
Insight appreciated
You will most likely want to do something like the following:
If you are trying to find the points on touch event points of a scaled image:
public static float[] getPointerCoords(ImageView view, MotionEvent e)
{
final int index = e.getActionIndex();
final float[] coords = new float[] { e.getX(index), e.getY(index) };
Matrix matrix = new Matrix();
view.getImageMatrix().invert(matrix);
matrix.postTranslate(view.getScrollX(), view.getScrollY());
matrix.mapPoints(coords);
return coords;
}
public boolean onTouch(View v, MotionEvent event)
{
float[] returnedXY = getPointerCoords((ImageView) v, event);
imageView.setLeft(returnedXY[0] + (imageView.getWidth() /2));
imageView.setTop(returnedXY[1] + (imageView.getHeight() /2));
}
if not, just use the events.getX and getY. You may need to use the getRawX and getRawY of the event.

Android Bitmap OnTouch Questions

I've drawn 5 bitmaps from .png files on a canvas - a head, a body and two arms and legs.
How can I detect which of these has been touched on an OnTouch? And, more specifically, can I detect if the OnTouch was within the actual shape of the body part touched?
What I mean is, obviously, the .pngs themselves are rectangular, but does Android know, or can I tell it, to ignore the transparency within the image?
You could get the colour of pixel touched and compare it to the colour of pixel on the background at those co-ords.
EDIT: ok, ignore that, you can't get the colour of a pixel on the canvas, so instead, get the x,y of the touch, check if any of the body part images have been touched, if so, take the x,y of the image from the touch x,y, then get the pixel of the image, which should be transparent or colour.
public boolean onTouchEvent(MotionEvent event)
{
int x = (int) event.getX();
int y = (int) event.getY();
int offsetx, offsety;
for(int i = 0;i<NUM_OF_BODY_PARTS;i++)
{
if(bodyPartRect[i].intersects(x,y,x+1,y+1))
{
offsetx = x - bodyPartRect[i].left;
offsety = y - bodyPartRect[i].top;
if(bodyPartBMP[i].getPixel(offsetx,offsety) == TRANSPARENT)
{
//whatever
}
}
}
}

Categories

Resources