Canvas draw rectangle android - android

public static Bitmap getCircularBitmapWithWhiteBorder(Bitmap bitmap,
int borderWidth) {
if (bitmap == null || bitmap.isRecycled()) {
return null;
}
final int width = bitmap.getWidth() + borderWidth;
final int height = bitmap.getHeight() + borderWidth;
Bitmap canvasBitmap = Bitmap.createBitmap(width*2, height, Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
Canvas canvas = new Canvas(canvasBitmap);
float radius = width > height ? ((float) height) / 2f : ((float) width) / 2f;
canvas.drawCircle(width / 2, height / 2, radius, paint);
paint.setShader(null);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(borderWidth);
canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2, paint);
return canvasBitmap;
}
I have circular image, i want to attach next to circular image sort of a rectangle..similar to his
this is a circle, next to it there is a rectangle attached. how can I do this?

You could draw your Rectangle more or less like this:
canvas.drawRect(width/2 + radius, height/2 - radius, width , height, paint);
just adjust the parameters for positioning it correctly if needed

Related

Full Text not showing into image

I am trying to convert text into image using below code :
public Bitmap textAsBitmap(String text, float textSize) {
Paint paint = new Paint(ANTI_ALIAS_FLAG);
paint.setTextSize(textSize);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setTextAlign(Paint.Align.CENTER);
float baseline = -paint.ascent(); // ascent() is negative
int width = (int) (paint.measureText(text) + 0.5f); // round
int height = (int) (baseline + paint.descent() + 0.5f);
Bitmap image = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
canvas.drawText(text, 0, baseline, paint);
return image;
}
Its convert text into image but problem is show half text.It should show "favorite subject is english"!
what i am doing wrong ? or how should i solve this problem
Choose your width & height wisely,
Something like I did in my case
public Bitmap textAsBitmap(String text, float textSize) {
Paint paint = new Paint(ANTI_ALIAS_FLAG);
paint.setTextSize(textSize);
paint.setColor(Color.BLACK);
paint.setTextAlign(Paint.Align.LEFT);
float baseline = -paint.ascent(); // ascent() is negative
int width = (int) (paint.measureText(text) + 0.0f); // round
int height = (int) (baseline + paint.descent() + 0.0f);
int actualWidth = width;
if (width > height)
height = width;
else
width = height;
Bitmap image = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(image);
canvas.drawText(text, width / 2 - actualWidth / 2, baseline, paint);
return image;
}
Problem is with paint.setTextAlign(Paint.Align.CENTER);, this property considers center as (0,0). So your text is actually at center according to (0,0).
Just remove paint.setTextAlign(Paint.Align.CENTER); and your code is working!!

Drawing a squircle shape on canvas (Android)

Here is what I'm using to draw a circle shape on to the canvas (and then an icon bitmap on it):
private static Bitmap makeIcon(int radius, int color, Bitmap icon) {
final Bitmap output = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(color);
canvas.drawARGB(0, 0, 0, 0);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint);
else
canvas.drawRect(0, 0, radius, radius, paint);
int cx = (radius - icon.getWidth()) >> 1; // same as (...) / 2
int cy = (radius - icon.getHeight()) >> 1;
canvas.drawBitmap(icon, cx, cy, paint);
icon.recycle();
return output;
}
But I have no idea on how to draw a squircle shape instead of the circle shape. FYI, here are some examples of icons using the squircle shape:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Path squirclePath = getSquirclePaath(150, 250, 400);
canvas.drawPath(squirclePath, mPaint);
}
private static Path getSquirclePaath(int left, int top, int radius){
//Formula: (|x|)^3 + (|y|)^3 = radius^3
final double radiusToPow = radius * radius * radius;
Path path = new Path();
path.moveTo(-radius, 0);
for (int x = -radius ; x <= radius ; x++)
path.lineTo(x, ((float) Math.cbrt(radiusToPow - Math.abs(x * x * x))));
for (int x = radius ; x >= -radius ; x--)
path.lineTo(x, ((float) -Math.cbrt(radiusToPow - Math.abs(x * x * x))));
path.close();
Matrix matrix = new Matrix();
matrix.postTranslate(left + radius, top + radius);
path.transform(matrix);
return path;
}
Here is a preview:
The other way is to use a BitmapShader.
Note: both mask and image must be equal size, so you have to resize your images.
Note2: this code is developed for Launcher icons and has poor Adaptive Icons adaptation yet.
baseIconSize is a «destination» size.
fun Drawable.toBitmap(width: Int, height: Int, config: Bitmap.Config): Bitmap {
val bitmap = Bitmap.createBitmap(width, height, config)
val canvas = Canvas(bitmap)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (this is AdaptiveIconDrawable) {
background.setBounds(0, 0, width, height)
background.draw(canvas)
foreground.setBounds(0, 0, width, height)
foreground.draw(canvas)
} else {
setBounds(0, 0, width, height)
draw(canvas)
}
} else {
setBounds(0, 0, width, height)
draw(canvas)
}
return bitmap
}
val maskBitmap = requireNotNull(context.getDrawable(R.drawable.mask_squircle))
.toBitmap(
width = baseIconSize,
height = baseIconSize,
config = Bitmap.Config.ALPHA_8
)
val iconBitmap = Bitmap.createBitmap(
baseIconSize,
baseIconSize,
Bitmap.Config.ARGB_8888
)
val originalBitmap = if (bitmap.width == baseIconSize && bitmap.height == baseIconSize) {
bitmap
} else {
bitmap.scale(baseIconSize, baseIconSize)
}
iconShapePaint.shader = BitmapShader(
originalBitmap,
Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT
)
val canvas = Canvas(iconBitmap)
canvas.drawBitmap(maskBitmap, 0f, 0f, iconShapePaint)
originalBitmap.recycle()
return iconBitmap
Before:
After:
Mask:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="1024dp"
android:height="1024dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M512,1024C736.36,1024 861.08,1024 942.54,942.54C1024,861.08 1024,736.36 1024,512C1024,287.64 1024,162.92 942.54,81.46C861.08,0 736.36,0 512,0C287.64,0 162.92,0 81.46,81.46C0,162.92 0,287.64 0,512C0,736.36 0,861.08 81.46,942.54C162.92,1024 287.64,1024 512,1024Z"
android:strokeWidth="1"
android:fillColor="#000000"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

How to draw a text in canvas in android [duplicate]

This question already has answers here:
How to draw text on canvas?
(3 answers)
Closed 8 years ago.
I am writing an application that consists of a gauge view. I downloaded from here and i want to draw text inside the gauge view (that is at the center of the gauge view) how can i draw a text inside a gauge view please help me.
After my friends answers in stack overflow i did it like this but it did not works please make it work
private void drawGauge()
{
if (null != mBackground)
{
mBackground.recycle();
}
/*--For Semi circle put getHeight()/2--*/
mBackground = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
newBitmap = Bitmap.createBitmap(mBackground.getWidth(), mBackground.getHeight(), Config.ARGB_8888);
Canvas newCanvas = new Canvas(newBitmap);
final Canvas canvas = new Canvas(mBackground);
final float scale = Math.min(getWidth(), getHeight());
canvas.scale(scale, scale);
canvas.translate((scale == getHeight()) ? ((getWidth() - scale) / 2) / scale : 0,(scale == getWidth()) ? ((getHeight() - scale) / 2) / scale : 0);
Paint paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
paintText.setColor(Color.WHITE);
paintText.setTextSize(50);
paintText.setTextAlign(Align.CENTER);
paintText.setStyle(Style.FILL);
Rect rectText = new Rect();
paintText.getTextBounds(captionString, 0, captionString.length(), rectText);
newCanvas.drawText(captionString, 0, rectText.height(), paintText);
//canvas.drawText("MedeQuip", 200, 500, shadowpaint);
//drawRim(canvas);
//drawFace(canvas);
For vipluv:
protected void onDraw(final Canvas canvas) {
drawBackground(canvas);
final float scale = Math.min(getWidth(), getHeight());
canvas.scale(scale, scale);
canvas.translate((scale == getHeight()) ? ((getWidth() - scale) / 2) / scale : 0, (scale == getWidth()) ? ((getHeight() - scale) / 2) / scale : 0);
if (mShowNeedle) {
drawNeedle(canvas);
}
if (mShowText) {
drawText(canvas);
}
Paint paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
paintText.setColor(Color.WHITE);
paintText.setTextSize(150);
paintText.setTextAlign(Align.CENTER);
paintText.setStyle(Style.FILL);
Rect rectText = new Rect();
paintText.getTextBounds(captionString, 0, captionString.length(), rectText);
canvas.drawText(captionString, rectText.width(), rectText.height(), paintText);
computeCurrentValue();
}
In the onDraw() function in their GaugeView.java file, add a canvas.drawText() just before the call to computeCurrentValue().
Use your own Paint object, and make sure you have initialized its textsize and color properties.

Draw circle with different border colors Android

public static Bitmap drawCircle(int width,int height, int borderWidth) {
Bitmap canvasBitmap = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(canvasBitmap, TileMode.CLAMP,
TileMode.CLAMP);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
paint.setShader(null);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.WHITE);
paint.setStrokeWidth(borderWidth);
Canvas canvas = new Canvas(canvasBitmap);
float radius = width > height ? ((float) height) / 2f : ((float) width) / 2f;
canvas.drawCircle(width / 2, height / 2, radius - borderWidth / 2, paint);
return canvasBitmap;
}
Simple this code draws a circle with white border, however I want part of the border to be black and the other part white. 40 % of it black, 60 % of it white
How can this be done?
Try this code
class MyView extends View
{
private Paint paint;
public MyView(Context context, int x, int y)
{
super(context);
paint = new Paint();
// PorterDuffXfermode xfermode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.RED);
paint.setAlpha(255);
// paint.setXfermode(xfermode);
paint.setAntiAlias(true);
// setBackgroundColor(Color.BLACK);
}
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawCircle(100, 100, 50, paint);
}
}
Here a utility method for filling a circle with one color and stroking the circle border with another color.
Use the second method to pass in an existing Paint instance, e.g. to set the anti-alias flag or to prevent memory allocations during onDraw().
public static void fillCircleStrokeBorder(
Canvas c, float cx, float cy, float radius,
int circleColor, float borderWidth, int borderColor) {
fillCircleStrokeBorder(c, cx, cy, radius, circleColor, borderWidth, borderColor, new Paint());
}
public static void fillCircleStrokeBorder(
Canvas c, float cx, float cy, float radius,
int circleColor, float borderWidth, int borderColor, Paint p) {
int saveColor = p.getColor();
p.setColor(circleColor);
Paint.Style saveStyle = p.getStyle();
p.setStyle(Paint.Style.FILL);
c.drawCircle(cx, cy, radius, p);
if (borderWidth > 0) {
p.setColor(borderColor);
p.setStyle(Paint.Style.STROKE);
float saveStrokeWidth = p.getStrokeWidth();
p.setStrokeWidth(borderWidth);
c.drawCircle(cx, cy, radius - (borderWidth / 2), p);
p.setStrokeWidth(saveStrokeWidth);
}
p.setColor(saveColor);
p.setStyle(saveStyle);
}
Just draw your circle at full size with one color, then draw the circles again at the same coordinate, but with a different color and with a smaller radius, and scale down the radius however much you need to, that would be the most trivial way to do it.

Circle drawn on canvas doesn't match the screen

I want to draw circle in center of screen, but I'm getting something like this:
I'm using this code to draw this circle.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
Canvas c = new Canvas(bmp);
RectF rect = new RectF(0,0,width,width);
drawCircle(rect, c, width, height);
ImageView img = (ImageView) findViewById(R.id.imageView1);
img.setImageBitmap(bmp);
img.setScaleType(ScaleType.FIT_CENTER);
}
private void drawCircle(RectF rect, Canvas c, int width, int height) {
Paint paint = new Paint();
paint.setARGB(255, 255 , 10, 21);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStyle(Paint.Style.STROKE);
int radius;
if(width < height)
radius = width/2;
else
radius = height/2;
c.drawCircle(width/2, height/2, radius, paint);
}
I don't understand why it's cut at sides even though I use size of screen to draw it, so it should perfectly fit it.
You didn't account for the thickness of the line (strokeWidth). You drew a circle assuming it had 0 thickness, so the "actual" circle IS touching the edges of the screen, but since you used a thick paintbrush, some of the paint leaked past the edge.
you should decrease the thickness/2.
private void drawCircle(RectF rect, Canvas c, int width, int height) {
Paint paint = new Paint();
paint.setARGB(255, 255 , 10, 21);
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStyle(Paint.Style.STROKE);
int radius;
if(width < height)
radius = width/2;
else
radius = height/2;
//this is the new line:
radius-= 5;
c.drawCircle(width/2, height/2, radius, paint);
}
Account for the StrokeWidth in the radius:
// Substract stroke width.
radius -= paint.getStrokeWidth() / 2;
c.drawCircle(width/2, height/2, radius, paint);

Categories

Resources