Draw text directly under a specified bitmap - java

p.setColor(Color.parseColor("#D32F2F"));
RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(), (float) itemView.getRight(), (float) itemView.getBottom());
c.drawRect(background, p);
icon = getBitmapFromVectorDrawable(MainActivity.this, R.drawable.ic_clear);
RectF icon_dest = new RectF((float) itemView.getRight() - 2 * width, (float) itemView.getTop() + width, (float) itemView.getRight() - width, (float) itemView.getBot
c.drawBitmap(icon, null, icon_dest, p); //[1]
p.setTextSize(50);
p.setColor(Color.WHITE);
c.drawText("Cancel",*/Insert x and y here*/,p);
So far I have that.
I'm trying to drawText directly under the bitmap I drawed. ([1]). However I'm not sure how to get the coordinates of the bitmap and adjust it so that it's centered below it.
The above image is what I'm trying to achieve. Contents of the app has been censored.
In conclusion, how do I get the coordinates for the text that I'm trying to get?
I'm using onChildDraw method of the ItemTouchHelper for a RecyclerView.

You can use paint.getTextBounds() to get the bounds of the text that you are about to draw on the canvas. Once you get the bounds of the text, you can calculate the position to draw the text based on the icon's position.
Edit:
This aligns the text below the icon at the X position same as the icon:
float textX = icon_dest.left;
float textY = icon_dest.bottom + some_padding;
canvas.drawText("Cancel", textX, textY, textPaint);
This aligns the center of the icon and the center of the text in a same vertical line:
Rect textBounds = new Rect();
textPaint.getTextBounds("Cancel", 0, length, textBounds);
float iconCenterX = icon_dest.left + (icon_dest.width() / 2);
float textHalfWidth = (textBounds.right - textBounds.left) / 2;
float textX = iconCenterX - textHalfWidth;
float textY = icon_dest.bottom + somePadding
canvas.drawText("Cancel", textX, textY, textPaint);

Related

Draw text on bitmap in the bottom left corner

I'm trying to draw some text on bitmap with a fixed position (Bottom left corner) no matter how bitmap size different.
Code below works but, the Text is drawn on the center of the bitmap
public Bitmap drawTextToBitmap(Context gContext,
Bitmap bitmap,
String gText) {
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
android.graphics.Bitmap.Config bitmapConfig =
bitmap.getConfig();
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(getResources().getColor(R.color.fujiColor));
paint.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/DS-DIGI.TTF"));
paint.setTextSize((int) (14 * scale));
paint.setShadowLayer(1f, 0f, 1f, getResources().getColor(R.color.fujiShadowColor));
Rect bounds = new Rect();
paint.getTextBounds(gText, 0, gText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width()) / 2;
int y = (bitmap.getHeight() + bounds.height()) / 2;
canvas.drawText(gText, x, y, paint);
return bitmap;
}
What I need is something similar to this :
Thank you.
As mentioned in the official docs, the text is drawn taking the (x,y) values as origin. Change the x,y values. Something along the following lines should work.
int horizontalSpacing = 24;
int verticalSpacing = 36;
int x = horizontalSpacing;//(bitmap.getWidth() - bounds.width()) / 2;
int y = bitmap.getHeight()-verticalSpacing;//(bitmap.getHeight() + bounds.height()) / 2;

Centering and Autosizing Text in Rect

I have a rectangle that I want to draw text inside. I want the text to be centered vertically and horizontally and I need the text size to changed to fit all characters inside the rectangle. Here is my code:
#Override
public void drawFixedText(String text, Rect rect, Paint paint) {
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
int cX = rect.left;
int cY = rect.top;
float textSize = paint.getTextSize();
paint.setTextSize(textSize);
float textWidth = paint.measureText(text);
while (textWidth > rect.width()) {
textSize--;
paint.setTextSize(textSize);
}
//if cX and cY are the origin coordinates of the your rectangle
//cX-(textWidth/2) = The x-coordinate of the origin of the text being drawn
//cY+(textSize/2) = The y-coordinate of the origin of the text being drawn
canvas.drawText(text, cX-(textWidth/2), cY+(textSize/2), paint);
}
I tried to combine the answers from Calculate text size according to width of text area and Android draw text into rectangle on center and crop it if needed
But it didn't work in that the text is placed to the left of the rectangle instead of inside of it. How can I fix this?
First, you need to measure the text width after each time setting its size. Otherwise, you'll end up with an infinite loop if the text starts out wider than the Rect.
while (textWidth > rect.width()) {
textSize--;
paint.setTextSize(textSize);
textWidth = paint.measureText(text);
}
Then, to center the text horizontally, you want to subtract half of the text width from the horizontal midpoint of the Rect, not from its left edge, which is what cX will be in your snippet. That is, replace cX - (textWidth / 2) with rect.centerX() - (textWidth / 2) in the drawText() call.
Furthermore, to center the text vertically, we'll need to do something similar with the y-coordinate. However, using the text size for that will not give the correct result. We need to measure the text's actual height and offset from baseline, which we can do using the Paint#getTextBounds() method.
Altogether, these changes would give something like:
public void drawFixedText(String text, Rect rect, Paint paint) {
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
float textSize = paint.getTextSize();
float textWidth = paint.measureText(text);
while (textWidth > rect.width()) {
textSize--;
paint.setTextSize(textSize);
textWidth = paint.measureText(text);
}
Rect bounds = new Rect();
paint.getTextBounds(text, 0, text.length(), bounds);
canvas.drawText(text,
rect.centerX() - textWidth / 2,
rect.centerY() - (bounds.top + bounds.bottom) / 2,
paint);
}
Please note that this assumes a default Paint instance. That is, any properties that affect text alignment have their default values going into this method.

How to rotate only the canvas behind the text

I have this function that animate the image canvas from resource drawable with text on the front.
I want to rotate the a green "star" only so the text stay intact
The idea is to rotate only the image canvas but no the text.
How do I do that?
This code is for Android Java
private Bitmap writeTextOnDrawable(int drawableId, String text, ImageView imv_promo,boolean isAnim) {
Bitmap bm = BitmapFactory.decodeResource(ctx.getResources(), drawableId).copy(Bitmap.Config.ARGB_8888, true);
Typeface tf = Typeface.createFromAsset(ctx.getAssets(), "RobotoCondensed-Italic.ttf");
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(ctx.getResources().getColor(R.color.white));
paint.setTypeface(tf);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(convertToPixels(mContext, 17));
Rect textRect = new Rect();
paint.getTextBounds(text, 0, text.length(), textRect);
Canvas canvas = new Canvas(bm);
//If the text is bigger than the canvas , reduce the font size
if (textRect.width() >= (canvas.getWidth() - 4)) //the padding on either sides is considered as 4, so as to appropriately fit in the text
paint.setTextSize(convertToPixels(mContext, 7)); //Scaling needs to be used for different dpi's
//Calculate the positions
int xPos = (canvas.getWidth() / 2) - 6; //-2 is for regulating the x position offset
int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2));
canvas.save();
canvas.rotate((float) 25, xPos, yPos);
canvas.drawText(text, xPos, yPos, paint);
canvas.restore();
Animation animation;
if(isAnim) {
animation = new RotateAnimation(0, 360, canvas.getWidth() / 2, canvas.getHeight() / 2);
animation.setRepeatMode(Animation.RESTART);
animation.setRepeatCount(Animation.INFINITE);
animation.setDuration(20000L);
imv_promo.startAnimation(animation);
}
return bm;
}

graph from html looking distorted when converting to pdf using itext

I am trying to convert html to pdf using itext Api but the issue is that my html has an element as well. so when I see the generated pdf the graph i.e in element looks distorted. my code in paint method is as below
#Override
public void paint(RenderingContext renderingContext, ITextOutputDevice outputDevice, BlockBox blockBox) {
PdfContentByte cb = outputDevice.getWriter().getDirectContent();
float width = (float) (cssWidth / outputDevice.getDotsPerPoint());
float height =(float) (cssHeight / outputDevice.getDotsPerPoint());
System.out.println("width :"+width+" height:"+height+" outputDevice.getDotsPerPoint(): "+outputDevice.getDotsPerPoint());
PdfTemplate template = cb.createTemplate(width, height);
Graphics2D g2d = template.createGraphics(width, height);
PrintTranscoder prm = new PrintTranscoder();
TranscoderInput ti = new TranscoderInput(svg);
prm.transcode(ti, null);
PageFormat pg = new PageFormat();
Paper pp = new Paper();
pp.setSize(width, height);
pp.setImageableArea(0, 0, width, height);
pg.setPaper(pp);
prm.print(g2d,pg, 0);
g2d.dispose();
PageBox page = renderingContext.getPage();
float x = blockBox.getAbsX() + page.getMarginBorderPadding(renderingContext, CalculatedStyle.LEFT);
float y = (page.getBottom() - (blockBox.getAbsY() + cssHeight)) + page.getMarginBorderPadding(renderingContext, CalculatedStyle.BOTTOM);
System.out.println("x " + x + " y" + y + " outputDevice.getDotsPerPoint() " + outputDevice.getDotsPerPoint());
x /= outputDevice.getDotsPerPoint();
y /= outputDevice.getDotsPerPoint();
cb.addTemplate(template, x, y);
System.out.println("Done with addition " + x + " " + y);
}
Now the changes that I observed is when I change float width = 400 and height = 620 then I see my graph coming but the top section disappears.
Can someone help me out with this issue. Also I think there must be some formulae for height and width so that the graph wont distort.
Thanks
The html that I am trying to convert is like this http://tinypic.com/r/e0o4xz/8 and the pdf I am getting is like http://i60.tinypic.com/14sz6kp.jpg So as you can see the pdf I am getting has missing x axis and the last bar of the chart is also missing. So the code part is like
float width = (float) (cssWidth / outputDevice.getDotsPerPoint());
float height = (float) (cssHeight / outputDevice.getDotsPerPoint());
So when I comment change the cssWidth=22000 and cssHeight=12000 then the chart comes with axis and the last bar is also coming thats in red but the alignment is distorted.

Align the texts center with the given position

I need to draw a text using
canvas.drawText("1",x,y, paint);
But the problem is that the "text's center" doesn't match with the position I have given,Is there any way I can do the latter.I have done quite a lot of search on the topic,culdn't find any answer.Please help.
Thank You in advance
You'll want to set the alignment on your paint instance:
paint.setTextAlign(Paint.Align.CENTER);
prior to drawing.
See: http://developer.android.com/reference/android/graphics/Paint.html#setTextAlign(android.graphics.Paint.Align)
Edit:
Per your indication that you'd also like it centered vertically, I'd go with an approach similar to this:
paint.setColor(Color.WHITE);
paint.setTextAlign(Align.LEFT);
String text = "Hello";
Rect bounds = new Rect();
float x = 100, y = 100;
paint.getTextBounds(text, 0, text.length(), bounds); // Measure the text
canvas.drawLine(0, y, canvas.getWidth(), y, paint); // Included to show vertical alignment
canvas.drawLine(x, 0, x, canvas.getHeight(), paint); // Included to show horizsontal alignment
canvas.drawText(text, x - bounds.width() * 0.5f, y + bounds.height() * 0.5f, paint); // Draw the text
or, using the center align on the paint:
paint.setColor(Color.WHITE);
paint.setTextAlign(Align.CENTER);
String text = "Hello";
Rect bounds = new Rect();
float x = 100, y = 100;
paint.getTextBounds(text, 0, text.length(), bounds); // Measure the text
canvas.drawLine(0, y, canvas.getWidth(), y, paint); // Included to show vertical alignment
canvas.drawLine(x, 0, x, canvas.getHeight(), paint); // Included to show horizsontal alignment
canvas.drawText(text, x, y + bounds.height() * 0.5f, paint); // Draw the text

Categories

Resources