Now I have an ImgeView which a circle and I want to find the center point of that circle so I have tried the following code but it seems not working
int[] location = new int[2];
imageView.getLocationOnScreen(location);
int radius=imageView.getHeight()/2;
int[] center=new int[2];
center[0]=location[0]+radius;
center[1]=location[1]+radius;
so the coordinates I got by "location" is top point of the imageview or not ?
Please help me how to get a center point of an imageview.
I assumed below situation:
You will be loading an ImageView(either from xml or code) and have a reference to the same in myImageView(say). Now, you wish to calculate the centre of the myImageView irrespective of its position on the screen.
If my assumption is correct then probably below is the solution you are looking for:
int centerXOnImage=myImageView.getWidth()/2;
int centerYOnImage=myImageView.getHeight()/2;
int centerXOfImageOnScreen=myImageView.getLeft()+centerXOnImage;
int centerYOfImageOnScreen=myImageView.getTop()+centerYOnImage;
You can get the top-left corner coordinates using:
ImageView iv = (ImageView)findViewById(R.id.image_view);
Rect rect = iv.getDrawable().getRect();
int xOffset = rect.left;
int yOffset = rect.top;
Based on height/2 and width/2 you can establish the center of your ImageView .
Addition to Chandan's answer,
say we are using the same code:
int centerXOnImage=myImageView.getWidth()/2;
int centerYOnImage=myImageView.getHeight()/2;
int centerXOfImageOnScreen=myImageView.getLeft()+centerXOnImage;
int centerYOfImageOnScreen=myImageView.getTop()+centerYOnImage;
if your myImageView.getWidth() is returning 0, you might want to do a little bit of modification:
myImageView.measure(0,0);
int centerXOnImage=myImageView.getMeasuredWidth()/2;
int centerYOnImage=myImageView.getMeasuredHeight()/2;
Notice, you might want to do this after myImageView is created in code and added to a root view.
Related
I have a set of imageButtons placed within a relative layout, and each imageButton has a shape within it that is visible while the rest of it is set to alpha. I have currently set these buttons to slightly overlap, and I am trying to code it so that when the alpha part of one button is pressed, it ignores that button and checks the button underneath it.
I am currently using onTouch() with an OnTouchListener to get the x and y coordinates of the touch on the screen, but that is calculated based on the whole screen from what I can tell. Is there a way to use the position found from event.getX() and event.getY() to look at where the button is on the screen and see if that spot clicked on the button is transparent or not?
Use View.getLocationOnScreen() and/or getLocationInWindow().
https://stackoverflow.com/a/2226048/1979882
In order to check if alpha-channel exists, I would use:
public static Bitmap loadBitmapFromView(View v) {
Bitmap bitmap;
v.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
return bitmap;
}
and than detect the ARGB value to a particular pixel.
int pixel = bitmap.getPixel(x,y);
Now you can get each channel with:
int alphaValue = Color.alpha(pixel);
int redValue = Color.red(pixel);
int blueValue = Color.blue(pixel);
int greenValue = Color.green(pixel);
https://stackoverflow.com/a/31775271/1979882
I know there are some similar topics that have been posted, but I couldn’t find a good solution for my problem.
I have a GridView which is filed with a custom ImageAdapter. Everything works fine, but whenever I click on an image contained in the GridView, I would like to move another Imageview at the click's position.
However, the coordinates of the Event, that I take with event.getX() and event.getY(), don’t correspond to the click’s position.
I first thought of a problem of dp/px conversion, and I tried several solutions in this way but none of them worked.
Then I tried to use the getXPrecision(), but I couldn’t make a working solution…
Maybe there is another way?
I would like to make the correct position programmatically, without adding constants int, so my project will work on various phone and tablet, with different dp and resolutions.
EDIT : Here is a screenshot, where i clicked the 3rd cell of the first line, and setted the position of the pencil with getRawX() - getRawY(). As we can see, this is not the correct position, I want the red dot (imageview's center) to be positionned where i clicked.
The code used :
//getting the position of the onTouch event :
GridView centre = (GridView) findViewById(R.id.gridView);
adapter = new ImageAdapter(this, (dim * dim), tailleCell);
centre.setAdapter(adapter);
centre.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View view, MotionEvent event) {
int X = (int)event.getRawX();
int Y = (int)event.getRawY();
animation(X, Y, etat);
return false;
}
});`
//launching the animation (and setting position of the pencil) :
private void animation(int posX, int posY, int etat)
{
final ImageView img;
if(etat == 0)
{
img = (ImageView) findViewById(R.id.imageView);
}
else
{
img = (ImageView) findViewById(R.id.imageView2);
}
img.clearAnimation();
img.setVisibility(View.VISIBLE);
img.setX(posX);
img.setY(posY);
[...]
}
EDIT 2 : ~Solution :
Jesus Molina Rodríguez De Vera's solution wasn't working as expected, but i managed to make a workable solution. I just changed my code in the Event Handler to adjust the image's position :
int[] offset = new int[2];
centre.getLocationOnScreen(offset);
int Xoffset=offset[0];
int Yoffset = offset[1];
int X = (int)event.getRawX();
int Y = (int)event.getRawY();
animation(X-((int)Math.round(Xoffset/1.15)), Y-((int)Math.round(Yoffset/1.5)), etat);
Sorry for my bad English :)
Thanks for your help!
Try using getRawX() and getRawY() instead of getX and getY.
Edit
I think that i have found the problem.
You are obtaining X and Y relative to the GridView top-left corner, not to the absolute screen coordinetes.
What you can do is the following:
int[] offset = new int[2];
center.getLocationOnScreen(offset);
int Xoffset=offset[0];
int Yoffset = offset[1];
private void animation(int posX, int posY, int etat){
//...
img.setX(posX+Xoffset);
img.setY(posY+Yoffset);
[...]
}
This is supposed to set the the top-left corner of the ImageView in the selected point. In order to set the center in that point:
int ivWidth = img.getWidth();
int ivHeight = img.getHeight();
private void animation(int posX, int posY, int etat){
//...
int[] finalPosition=new int[2];
finalPosition[0] = posX+Xoffset-(ivWidth/2);
finalPosition[1] = posY+Yoffset-(ivHeight/2);
img.setX(finalPosition[0]);
img.setY(finalPosition[1]);
[...]
}
I haven't try it but it should work.
Edit 2
Xoffset and Yoffset are only needed if you use getX()/getY() instead of getRawX()/getRawY()
I need to draw something like this:
I was hoping that this guy posted some code of how he drew his segmented circle to begin with, but alas he didn't.
I also need to know which segment is where after interaction with the wheel - for instance if the wheel is rotated, I need to know where the original segments are after the rotation action.
Two questions:
Do I draw this segmented circle (with varying colours and content placed on the segment) with OpenGL or using Android Canvas?
Using either of the options, how do I register which segment is where?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
EDIT:
Ok, so I've figured out how to draw the segmented circle using Canvas (I'll post the code as an answer). And I'm sure I'll figure out how to rotate the circle soon. But I'm still unsure how I'll recognize a separate segment of the drawn wheel after the rotation action.
Because, what I'm thinking of doing is drawing the segmented circle with these wedges, and the sort of handling the entire Canvas as an ImageView when I want to rotate it as if it's spinning. But when the spinning stops, how do I differentiate between the original segments drawn on the Canvas?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I've read about how to draw a segment on its own (here also), OpenGL, Canvas and even drawing shapes and layering them, but I've yet to see someone explaining how to recognize the separate segments.
Can drawBitmap() or createBitmap() perhaps be used?
If I go with OpenGL, I'll probably be able to rotate the segmented wheel using OpenGL's rotation, right?
I've also read that OpenGL might be too powerful for what I'd like to do, so should I rather consider "the graphic components of a game library built on top of OpenGL"?
This kind of answers my first question above - how to draw the segmented circle using Android Canvas:
Using the code found here, I do this in the onDraw function:
// Starting values
private int startAngle = 0;
private int numberOfSegments = 11;
private int sweepAngle = 360 / numberOfSegments;
#Override
protected void onDraw(Canvas canvas) {
setUpPaint();
setUpDrawingArea();
colours = getColours();
Log.d(TAG, "Draw the segmented circle");
for (int i = 0; i < numberOfSegments; i++) {
// pick a colour that is not the previous colour
paint.setColor(colours.get(pickRandomColour()));
// Draw arc
canvas.drawArc(rectF, startAngle, sweepAngle, true, paint);
// Set variable values
startAngle -= sweepAngle;
}
}
This is how I set up the drawing area based on the device's screen size:
private void setUpDrawingArea() {
Log.d(TAG, "Set up drawing area.");
// First get the screen dimensions
Point size = new Point();
Display display = DrawArcActivity.this.getWindowManager().getDefaultDisplay();
display.getSize(size);
int width = size.x;
int height = size.y;
Log.d(TAG, "Screen size = "+width+" x "+height);
// Set up the padding
int paddingLeft = (int) DrawArcActivity.this.getResources().getDimension(R.dimen.padding_large);
int paddingTop = (int) DrawArcActivity.this.getResources().getDimension(R.dimen.padding_large);
int paddingRight = (int) DrawArcActivity.this.getResources().getDimension(R.dimen.padding_large);
int paddingBottom = (int) DrawArcActivity.this.getResources().getDimension(R.dimen.padding_large);
// Then get the left, top, right and bottom Xs and Ys for the rectangle we're going to draw in
int left = 0 + paddingLeft;
int top = 0 + paddingTop;
int right = width - paddingRight;
int bottom = width - paddingBottom;
Log.d(TAG, "Rectangle placement -> left = "+left+", top = "+top+", right = "+right+", bottom = "+bottom);
rectF = new RectF(left, top, right, bottom);
}
That (and the other functions which are pretty straight forward, so I'm not going to paste the code here) draws this:
The segments are different colours with every run.
I want to change the HSV of bitmap I found out some help online but they are changing the HSV of whole image. In my case i have circular selector that enable user to select specific part of image and than change its HSV. It look like this
Can we do that without using any other third party image processing library?
If you know how to specifically get the pixel indices of the circle here is what you do:
int pixel = bitmap.getPixel(X,Y);
float[] HSV=new float[3];
Color.RGBToHSV(Color.red(pixel), Color.green(pixel), Color.blue(pixel), HSV);
// Manipulate the HSV array as you want then,
bitmap.setPixel(X,Y, Color.HSVToColor(HSV));
PS: If you want to know how to get the X and Y coordinates of pixel please do comment. I'll edit the post as per your requirements.
EDIT :
Here is how you get pixels of the circular area (and manipulate it) provided you have the co-ordinate of the center of the circle and the radius of the circle you want the manipulation to.
int centerX = 100; // This is the X co-ordinate of the center of your circle
int centerY = 100; // This is the Y co-ordinate of the center of your circle
int radius = 40; // This is the radius of the circle you want
for(int Y=centerY-radius; Y<=centerY+radius;Y++)
{
for(int X=centerX-radius;X<=centerX+radius;X++)
{
int distance = (int)Math.sqrt(Math.pow((X-centerX),2) + Math.pow((Y-centerY),2));
if(distance<=radius)
{
int pixel = bitmap.getPixel(X,Y);
float[] HSV=new float[3];
Color.RGBToHSV(Color.red(pixel), Color.green(pixel), Color.blue(pixel), HSV);
// Manipulate the HSV array as you want then,
bitmap.setPixel(X,Y, Color.HSVToColor(Color.alpha(pixel),HSV));
}
}
}
you can use Bitmap.setPixel(int, int, int); , to change the color at position(x, y).
or
you can create a canvas use from a bitmap use
Canvas canvas = new Canvas(bitmap);
and you can add new content on the original bitmap.
I check the Internet and see using ZXing to solve two-dimension code. But the code I do not understand.
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource( data, width, height, dstLeft, dstTop, dstWidth,dstHeight, false);
What the meaning of the parameter?
I went to read the ZXing source code and I found the following (There was no constructor with boolean parameter in the end)
PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth, int dataHeight, int left,
int top, int width, int height)
{
super(width, height);
if (left + width > dataWidth || top + height > dataHeight)
{
throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
}
this.yuvData = yuvData;
this.dataWidth = dataWidth;
this.dataHeight = dataHeight;
this.left = left;
this.top = top;
}
When I read the code I understand the following (I have an assumption that the relevant data consider only as the area of the inner rectangle of where the QR code should be placed in the image).
byte[] yuvData - The byte array that contain the data of the image. All the data the one inside the rectangle and outside of it.
int dataWidth - The width of the data. The width of the data all the area outside and inside the rectangle.
int dataHeight - The Height of the data. The height of the data all the area outside and inside the rectangle.
int left - The left border of the rectangle. Or, how many pixels are outside of the rectangle from the left.
int top - The top border of the rectangle. Or, how many pixels are outside of the rectangle from the top.
int width - The width of the inner rectangle.
int height - The height of the inner rectangle.