Following is code of onDraw function. It draws the circle and functions properly, but when I output circle coordinates in LOGCAT I don't see anything. I have imported the "android.Util.Log" as well,
Log.d command not showing in Logcat.
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
int pl = getPaddingLeft();
int pr = getPaddingRight();
int pt = getPaddingTop();
int pb = getPaddingBottom();
int usableWidth = w - (pl + pr);
int usableHeight = h - (pt + pb);
int radius = Math.min(usableWidth, usableHeight) / 2;
int cx = pl + (usableWidth / 2);
int cy = pt + (usableHeight / 2);
paint.setColor(circleColor);
//canvas.drawCircle(w, h, (radius * 1.5f), paint);
Log.d("CIRCLE DRAW", "Circle coordinates are as ");// +
//"X: "+ w +
//"Y: "+ h);
}
Related
I have the current code which draw a bounding box around a user's face on a live camera preview.
I am also trying to draw the position of facial landmarks on the live camera preview. It draws them but not at the right location due to not having the scale value
I found this code online but am struggling to compute this scale value as it is a live camera preview and not a bitmap image
Example code found online
double scale = Math.min( viewWidth / imageWidth, viewHeight / imageHeight );
for (Landmark landmark : face.getLandmarks()) {
int cx = (int) (landmark.getPosition().x * scale);
int cy = (int) (landmark.getPosition().y * scale);
canvas.drawCircle(cx, cy, 10, paint);
}
My Function
#Override
public void draw(Canvas canvas) {
Face face = mFace;
if (face == null) {
return;
}
// Draws a circle at the position of the detected face, with the face's track id below.
float x = translateX(face.getPosition().x + face.getWidth() / 2);
float y = translateY(face.getPosition().y + face.getHeight() / 2);
canvas.drawCircle(x, y, FACE_POSITION_RADIUS, mFacePositionPaint);
// Draws a bounding box around the face.
float xOffset = scaleX(face.getWidth() / 2.0f);
float yOffset = scaleY(face.getHeight() / 2.0f);
float left = x - xOffset;
float top = y - yOffset;
float right = x + xOffset;
float bottom = y + yOffset;
canvas.drawRect(left, top, right, bottom, mBoxPaint);
Paint paint = new Paint();
paint.setColor( Color.GREEN );
paint.setStyle( Paint.Style.STROKE );
paint.setStrokeWidth( 5 );
for ( Landmark landmark : face.getLandmarks() ) {
int cx = (int) ( landmark.getPosition().x);
int cy = (int) ( landmark.getPosition().y);
canvas.drawCircle( cx, cy, 10, paint );
}
}
Solved via the following, but not wholly accurate
if ((contains(face.getLandmarks(), 11) != 99)
&& (contains(face.getLandmarks(), 5) != 99)
&& (contains(face.getLandmarks(), 6) != 99)
) {
Log.i(TAG, "draw: Mouth Open >> found all the points");
/**
* for bottom mouth
*/
int cBottomMouthX;
int cBottomMouthY;
cBottomMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().x);
cBottomMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 0)).getPosition().y);
Log.i(TAG, "draw: Condition Bottom mouth >> cBottomMouthX >> " + cBottomMouthX + " cBottomMouthY >> " + cBottomMouthY);
canvas.drawCircle(cBottomMouthX, cBottomMouthY, 10, paint);
/**
* for left mouth
*/
int cLeftMouthX;
int cLeftMouthY;
cLeftMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().x);
cLeftMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().y);
Log.i(TAG, "draw: Condition LEft mouth >> cLeftMouthX >> " + cLeftMouthX + " cLeftMouthY >> " + cLeftMouthY);
cLeftMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().x);
cLeftMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 5)).getPosition().y);
canvas.drawCircle(cLeftMouthX, cLeftMouthY, 10, paint);
/**
* for Right mouth
*/
int cRightMouthX;
int cRightMouthY;
cRightMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().x);
cRightMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().y);
Log.i(TAG, "draw: Condition Right mouth >> cRightMouthX >> " + cRightMouthX + " cRightMouthY >> " + cRightMouthY);
cRightMouthX = (int) translateX(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().x);
cRightMouthY = (int) translateY(face.getLandmarks().get(contains(face.getLandmarks(), 11)).getPosition().y);
canvas.drawCircle(cRightMouthX, cRightMouthY, 10, paint);
float centerPointX = (cLeftMouthX + cRightMouthX) / 2;
float centerPointY = ((cLeftMouthY + cRightMouthY) / 2) - 20;
canvas.drawCircle(centerPointX, centerPointY, 10, paint);
float differenceX = centerPointX - cBottomMouthX;
float differenceY = centerPointY - cBottomMouthY;
Log.i(TAG, "draw: difference X >> " + differenceX + " Y >> " + differenceY);
if (differenceY < (-60)) {
Log.i(TAG, "draw: difference - Mouth is OPENED ");
} else {
Log.i(TAG, "draw: difference - Mouth is CLOSED ");
}
}
}
private int contains (List < Landmark > list,int name){
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getType() == name) {
return i;
}
}
return 99;
}
Can someone explain me how I can set that canvas doesnt draw circle outside the screen?
In screenshot it looks like this -
Click here to see image
As you can see, some of the circles is half outside the screen but I want that all of the circle is inside the screen.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Random random = new Random();
int minRadius = 50;
int w = this.getWidth();
int h = this.getHeight();
Paint paint = new Paint();
for (int i=0; i<resultInt; i++) {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
int randX = random.nextInt(w);
int randY = random.nextInt(h);
int color = Color.rgb(red, green, blue);
paint.setColor(color);
canvas.drawCircle(randX, randY, minRadius, paint);
}
}
}
}
You have to subtract your double radius:
int w = this.getWidth() - 2 * minRadius;
int h = this.getHeight() - 2 * minRadius;
And then fix random point:
int randX = random.nextInt(w) + minRadius;
int randY = random.nextInt(h) + minRadius;
int w = this.getWidth() - minRadius * 2;
int h = this.getHeight() - minRadius * 2;
...
int randX = random.nextInt(w) + minRadius;
int randY = random.nextInt(h) + minRadius;
I am trying to draw a circle progress bar around an circle image. I have tried to create my own "CircleImageView" Class which extends "ImageView"
my onDraw() method
protected void onDraw(Canvas canvas) {
canvas.drawCircle(mCenter[0], mCenter[1], mRadius, ringPaint);
progress = 30; //for testing
float angle = 360 * progress / maxProgress;
canvas.drawArc(mOval, mStartAngle, angle, false, progressPaint);
super.onDraw(canvas);
}
onMeasure method()
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
final int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int min = Math.min(width, height);
setMeasuredDimension(width, height);
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);
// Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
final float scaleX = f[Matrix.MSCALE_X];
final float scaleY = f[Matrix.MSCALE_Y];
// Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
final Drawable d = getDrawable();
final int origW = d.getIntrinsicWidth();
final int origH = d.getIntrinsicHeight();
// Calculate the actual dimensions
final int actW = Math.round(origW * scaleX);
final int actH = Math.round(origH * scaleY);
Log.e("DBG", "[" + origW + "," + origH + "] -> [" + actW + "," + actH + "] & scales: x=" + scaleX + " y=" +
scaleY);
mCenter = new int[]{width / 2, height / 2};
mRadius = (int) mCenter[0] - actW - progressStrokeWidth / 2;
mOval.set(mCenter[0] - mRadius, mCenter[1] - mRadius, mCenter[0] + mRadius, mCenter[1] + mRadius); //mOval is an instance of RectF
}
init() method
private void init(Context context, AttributeSet attrs) {
mContext = context;
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CircleProgressAttr);
progressStrokeWidth = typedArray.getInteger(R.styleable.CircleProgressAttr_progressRingSize, 20);
mRingColor = typedArray.getInt(R.styleable.CircleProgressAttr_progressRingColor, R.color.ringColor);
mProgressColor = typedArray.getInt(R.styleable.CircleProgressAttr_progressColor, R.color.tab_underline_color);
mStartAngle = -90;
maxProgress = 100;
mOval = new RectF();
ringPaint = new Paint();
progressPaint = new Paint();
ringPaint.setColor(mRingColor);
ringPaint.setStyle(Paint.Style.STROKE);
ringPaint.setStrokeWidth(progressStrokeWidth);
ringPaint.setAntiAlias(true);
progressPaint.setColor(mProgressColor);
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setStrokeWidth(progressStrokeWidth);
progressPaint.setAntiAlias(true);
}
I have inserted the CircleView into a RelativeLayout with the following XML-code
<com.kevinwang.simpleplayer.CircleImageView
android:id="#+id/cd_img"
android:src="#drawable/cd01"
android:layout_above="#id/play_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"/>
I ran the app, but the progressbar didn't show, is there anything wrong with my code ?
pic:
How should I do to custom the specific seekbar like the pic?
I think the point is:
When finger is moving on the seekbar, how to present a suspended view showing the progress.
There are some views which layer is same level to parent view of seekbar, these views are near the seekbar, would these views overlap the suspended view?
Take a look at this answer: 13887556
It could be a good starting point.
Try to extend SeekBar and override onMeasure() and onDraw methods():
#Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (labelBackground != null)
{
viewWidth = getMeasuredWidth();
barHeight = getMeasuredHeight();// returns only the bar height (without the label);
setMeasuredDimension(viewWidth, barHeight + labelBackground.getHeight());
}
}
#Override
protected synchronized void onDraw(Canvas canvas)
{
if (labelBackground != null)
{
barBounds.left = getPaddingLeft();
barBounds.top = labelBackground.getHeight() + getPaddingTop();
barBounds.right = barBounds.left + viewWidth - getPaddingRight() - getPaddingLeft();
barBounds.bottom = barBounds.top + barHeight - getPaddingBottom() - getPaddingTop();
progressPosX = barBounds.left + ((float) this.getProgress() / (float) this.getMax()) * barBounds.width();
labelPos.x = (int) progressPosX - labelOffset;
labelPos.y = getPaddingTop();
progressDrawable = getProgressDrawable();
progressDrawable.setBounds(barBounds.left, barBounds.top, barBounds.right, barBounds.bottom);
progressDrawable.draw(canvas);
labelTextPaint.getTextBounds(labelText, 0, labelText.length(), labelTextRect);
canvas.drawBitmap(labelBackground, labelPos.x, labelPos.y, labelBackgroundPaint);
canvas.drawText(labelText, labelPos.x + labelBackground.getWidth() / 2 - labelTextRect.width() / 2, labelPos.y + labelBackground.getHeight() / 2 + labelTextRect.height() / 2, labelTextPaint);
thumbX = (int) progressPosX - getThumbOffset();
thumbDrawable.setBounds(thumbX, barBounds.top, thumbX + thumbDrawable.getIntrinsicWidth(), barBounds.top + thumbDrawable.getIntrinsicHeight());
thumbDrawable.draw(canvas);
} else
{
super.onDraw(canvas);
}
i want my bitmap in the center of my screen..i m trying it that way but its not working...
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass);
int w = canvas.getWidth();
int h = canvas.getHeight();
int bw=myBitmap.getWidth();
int bh=myBitmap.getHeight();
int cx = w / 2;
int cy = h / 2;
Display d = getWindowManager().getDefaultDisplay();
int x = d.getWidth();
int y = d.getHeight();
int dx = x / 2;
int dw = y /2;
canvas.translate(cx, cy);
if (mValues != null) {
canvas.rotate(-mValues[0]);
}
int centreX = (x - bw) /2;
int centreY = (cy - bh) /2;
//canvas.drawPath(mPath, mPaint);
canvas.drawBitmap(myBitmap, centreX,centreY, null);
Here's the code you need in your view:
private int mWidth;
private int mHeight;
private float mAngle;
#Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
mWidth = View.MeasureSpec.getSize(widthMeasureSpec);
mHeight = View.MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(mWidth, mHeight);
}
#Override protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.compass);
// Here's the magic. Whatever way you do it, the logic is:
// space available - bitmap size and divide the result by two.
// There must be an equal amount of pixels on both sides of the image.
// Therefore whatever space is left after displaying the image, half goes to
// left/up and half to right/down. The available space you get by subtracting the
// image's width/height from the screen dimensions. Good luck.
int cx = (mWidth - myBitmap.getWidth()) >> 1; // same as (...) / 2
int cy = (mHeight - myBitmap.getHeight()) >> 1;
if (mAngle > 0) {
canvas.rotate(mAngle, mWidth >> 1, mHeight >> 1);
}
canvas.drawBitmap(myBitmap, cx, cy, null);
}
Screenshot just for fun: http://imgur.com/EYpMJ
(Diagonal lines not part of the code posted here)
EDIT: Added NickT's solution.
EDIT 2: Changed mvalues[0] to mAngle and made it conditional. Changed divide by 2 operations to bitshifts. Remove rotation code if you don't need it.
You can try this :
int width = containerBitmap.getWidth();
int height = containerBitmap.getHeight();
float centerX = (width - centeredBitmap.getWidth()) * 0.5f;
float centerY = (height- centeredBitmap.getHeight()) * 0.5f;
You can use it to draw a bitmap at the center of another bitmap.