I want to take user input in numbers and based on that input I want to draw multiple numbers of rectangles on screen using for loop.
This is the image that I want to implement.
thank you in advance.
There are several ways to do this. Probably the simplest way is to draw rects to a canvas using 2 nested for loops, like so:
for (int n = 0; n < numRows; n++){
for (int m = 0; m < numColumns; m++){
canvas.drawRect(leftMargin + m*columnWidth, topMargin + n*rowHeight,
leftMargin + m*columnWidth + width, topMargin + n*rowHeight + height, myPaint);
}
}
where:
numRows = # of rows to draw
numColumns = # of columns to draw
leftmargin = distance from left side of screen to first column
topMargin = distance from top of screen to first row
columnWidth = width of each column of rects
rowHeight = heigth of each row of rects
width = width of each rect, if equal to columnWidth there will be no space between rects.
height = height of each rect, if equal to rowHeight there will be no space between.
myPaint = the Paint object you define for your rects, where you would specify things like color, filled in or outline, opacity, etc.
Related
How can I draw line/arc with rounded corners as you can see on the picture below?
I need to draw this on Canvas.
I think you can workaround this by drawing three lines with a partial overlap:
two external lines with Paint.Cap.ROUND
one inner line with Paint.Cap.BUTT
Assuming your input data is
float lineWidth = 20;
float lineRadius = 100;
float cornerRadius = 2;
You go as follows,
float width, radius;
// Draw outer lines
paint.setStrokeCap(Paint.Cap.ROUND);
width = cornerRadius * 2;
// Draw inner
radius = lineRadius - lineWidth/2f + cornerRadius;
canvas.draw(...)
// Draw outer
radius = lineRadius + lineWidth/2f - cornerRadius;
canvas.draw(...)
// Draw center
paint.setStrokeCap(Paint.Cap.BUTT);
width = lineWidth - 2f*cornerRadius;
radius = lineRadius;
canvas.draw(...)
You might need to slightly alter the arc angle for the center line (it must be cornerRadius longer, on each side) but that is easy.
What is happening from line #129 to line #133 in this class of the Color blob detection sample app?
SOME CONTEXT:
The camera view in the app looks like this: (Notice that in the camera view, there is a black border around the camera frame)
(If you can't see the image, check it here.)
From Line 114 to 128, the following is happening.
int cols = mRgba.cols(); cols() gives the number of columns in a matrix. The matrix here is the Mat representing a frame in the live stream of frames being displayed (and not the entire camera view), i.e. it represents the part of the camera view where live stream is being displayed, EXCLUDING the black border of the camera view.
int rows = mRgba.rows(); rows() gives the number of rows in the camera frame, EXCLUDING the black border of the camera view.
int xOffset = (mOpenCvCameraView.getWidth() - cols) / 2; int yOffset = (mOpenCvCameraView.getHeight() - rows) / 2; mOpenCvCameraView.getWidth() gives the number of rows in the entire camera view, i.e. the camera frame PLUS the black border of the camera view around the frame. (mOpenCvCameraView.getWidth() - cols) gives the sum of the width of left and right black border of the camera view. (mOpenCvCameraView.getWidth() - cols)/2 or xOffset gives the width of the black border on one side, i.e. either right or left side, black border of the camera view. Likewise for yOffset
int x = (int)event.getX() - xOffset; int y = (int)event.getY() - yOffset; getX() returns the X coordinate of this event for the first pointer index. So getX() gives the distance of the touched region from the left extreme side of the camera view, which includes the black border on the left. So event.getX()-xOffset or int x is the distance of the touched region from the left extreme side of the camera "frame" (which does NOT include the black border of the camera view). Likewise for int y.
Then are the lines which I have no clue about.
I assume you're asking about these lines:
touchedRect.x = (x>4) ? x-4 : 0;
touchedRect.y = (y>4) ? y-4 : 0;
touchedRect.width = (x+4 < cols) ? x + 4 - touchedRect.x : cols - touchedRect.x;
touchedRect.height = (y+4 < rows) ? y + 4 - touchedRect.y : rows - touchedRect.y;
From what I can tell, it's basically just making sure that Rectangle height and width don't wander out of frame.
Breakdown of why -
The ? operator (called the ternary operator) in Java is basically a shorthand of if/else - the line touchedRect.x = (x>4) ? x-4 : 0 means
if (x>4) {
touchedRect.x = x-4;
} else {
touchedRect.x = 0;
}
So, for line 129, if x > 4, set touchedRect.x to x-4, else 0.
line 130, if y > 4, set touchedRect.y to y-4, else 0.
line 131, touchedRect.width becomes x+4 - touchedRect.x if x+4 < cols, else touchedRect.width becomes cols - touchedRect.x
line 132, touchedRect.height becomes y+4-touchedRect.y if y+4 < rows, else it becomes rows - touchedRect.y
I am creating a Custom View where I have to draw text at specific positions on the canvas. For using canvas.drawText() we have to create a paint object that has to be passed as a parameter while calling the drawText(). If I want to get the text to be rendered as centrally aligned, I am using the setTextAlign() call while making the paint object.
statPaint.setTextAlign(Paint.Align.CENTER);
Also when I call the drawText(), I am required to set the starting point for the text to be rendered, as shown below.
canvas.drawText(stat1,paddingLeft,paddingTop,statPaint);
paddingLeft and paddingTop tell the drawText() where to draw the text from. Passing these two parameters is mandatory for the function call. But I still am not able to get the text centrally aligned. How do I get this text centrally aligned.
Also if I want to get two different texts in the same line, the first one being centrally aligned in the first half of the screen, and the second text, centrally aligned in the second half of the screen, how do I do that? The screen is divided into halves vertically.
Thanks in advance.
Here is how to center text in any rectangle (just change left/right/top/bottom)
// Allocated once as a member var, not in each onDraw
private Rect rect = new Rect();
// Inside onDraw
int left = 0;
int right = getWidth();
int top = 0;
int bottom = getHeight();
paint.getTextBounds(text, 0, text.length(), rect);
FontMetrics fm = paint.getFontMetrics();
float x = left + (right - left - rect.width()) / 2;
float y = top + (bottom - top) / 2 - (fm.descent + fm.ascent) / 2;
canvas.drawText(text, x, y, paint);
I have a classic ImageView that is resized to fit its parent with match_parent on both axes and scaleType is fitCenter.
The coordinates I get out of an onTouch event, however, are relative to the bounds of the ImageView. How can I convert them to be relative to the bounds of the image itself?
UPDATE
I ended up doing this manually. This is in Scala, but probably easy to translate into Java :
// Long press on the screen adds a new interaction at that position
screenView onTouch {
(v: View, ev: MotionEvent) => {
// Create the image transformation matrix
val m = screenView.getImageMatrix
val d = screenView.getDrawable
val drawableRect = new RectF(0, 0, d.getIntrinsicWidth, d.getIntrinsicHeight)
val viewRect = new RectF(0, 0, screenView.getWidth, screenView.getHeight)
m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER)
m.invert(m)
// Convert the points inside the image
val points = Array(ev.getX, ev.getY)
m mapPoints points
// Compute normalized coordinates
current_x = points(0) / d.getIntrinsicWidth
current_y = points(1) / d.getIntrinsicHeight
// Only continue if we touched inside the image
!(current_x >= 0 && current_x <= 1 &&
current_y >= 0 && current_y <= 1)
}
}
You can calculate it mathematically.
Compute the ratio between height & width of the image, then calculate the actual width of the image as displayed.
Subtract the image's actual width from the imageview's width, and divide by two.
This will give you the width of the grey area left of the image. Simply subtract this number from the X coordinates you got, and you will get the relative X position from the actual image.
I am using Canvas.drawCircle to draw a circle in Android laout.
Method gets 3 parameters - first two are position - x and y.
Is it possible to skip hardcoded position of the circle and draw it centered ?
Following code can be used to get the width and height of the screen.
int width = this.getWidth();
int height = this.getHeight();
To draw circle in the middle of screen you can call :
Canvas.drawCircle(width/2, height/2)
You can paint a circle centered to the screen like this:
Display disp = ((WindowManager)this.getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
canvas.drawCircle(disp.getWidth()/2, disp.getHeight()/2, radius, paint);
Assuming you are extending the View class:
int CentreX = (this.getWidth() / 2);
int CentreY = (this.getHeight() / 2);