android draw stroke on multi line text - android

Hi i'am trying to add stroke on multi line text but its not working
this is the code
first draw the fill text its works fine
but when try to draw the stroke it's not work and give me something that not related to stroke
i need stroke like this but to multi line text
stroke canvas
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextSize(20);
textPaint.setColor(Color.White);
textPaint1.setStyle(Paint.Style.STROKE);
textPaint1.setStrokeWidth(20);
textPaint1.setColor(Color.GREEN);
StaticLayout sl = new StaticLayout(
textLayer.getText(), // - text which will be drawn
textPaint,
boundsWidth, // - width of the layout
Layout.Alignment.ALIGN_CENTER, // - layout alignment
1, // 1 - text spacing multiply
1, // 1 - text spacing add
true); // true - include padding
int boundsHeight = sl.getHeight();
int bmpHeight = (int) (canvasHeight * Math.max(TextLayer.Limits.MIN_BITMAP_HEIGHT,
1.0F * boundsHeight / canvasHeight));
// create bitmap where text will be drawn
Bitmap bmp;
if (reuseBmp != null && reuseBmp.getWidth() == boundsWidth
&& reuseBmp.getHeight() == bmpHeight) {
// if previous bitmap exists, and it's width/height is the same - reuse it
bmp = reuseBmp;
bmp.eraseColor(Color.TRANSPARENT); // erase color when reusing
} else {
bmp = Bitmap.createBitmap(boundsWidth, bmpHeight, Bitmap.Config.ARGB_8888);
}
StaticLayout sl1 = new StaticLayout(
textLayer.getText(), // - text which will be drawn
textPaint1,
boundsWidth, // - width of the layout
Layout.Alignment.ALIGN_CENTER, // - layout alignment
1, // 1 - text spacing multiply
1, // 1 - text spacing add
true); // true - include padding
// calculate height for the entity, min - Limits.MIN_BITMAP_HEIGHT
int boundsHeight1 = sl1.getHeight();
int bmpHeight1 = (int) (canvasHeight * Math.max(TextLayer.Limits.MIN_BITMAP_HEIGHT,
1.0F * boundsHeight1 / canvasHeight));
Bitmap bmp1;
if (reuseBmp != null && reuseBmp.getWidth() == boundsWidth
&& reuseBmp.getHeight() == bmpHeight1) {
// if previous bitmap exists, and it's width/height is the same - reuse it
bmp1 = reuseBmp;
bmp1.eraseColor(Color.TRANSPARENT); // erase color when reusing
} else {
bmp1 = Bitmap.createBitmap(boundsWidth, bmpHeight, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bmp);
canvas.save();
Canvas canvas1 = new Canvas(bmp1);
canvas1.save();
// move text to center if bitmap is bigger that text
if (boundsHeight < bmpHeight) {
//calculate Y coordinate - In this case we want to draw the text in the
//center of the canvas so we move Y coordinate to center.
float textYCoordinate = (bmpHeight - boundsHeight) / 2;
canvas.translate(0, textYCoordinate);
}
// move text to center if bitmap is bigger that text
if (boundsHeight1 < bmpHeight1) {
//calculate Y coordinate - In this case we want to draw the text in the
//center of the canvas so we move Y coordinate to center.
float textYCoordinate = (bmpHeight1 - boundsHeight1) / 2;
canvas1.translate(0, textYCoordinate);
}
//draws static layout on canvas
sl.draw(canvas);
sl1.draw(canvas1);
canvas.restore();
canvas1.restore();
and this to combine the bitmaps
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas2 = new Canvas(bmOverlay);
canvas2.drawBitmap(bmp, new Matrix(), null);
canvas2.drawBitmap(bmp1, 0, 0, null);
return bmOverlay;
return bmp;

You need to create two StaticLayout with the same text, but one with the text paint, the other with the stroke paint, then draw at the same position.

Related

How to add background color for staticLayout in Android

I want to add background color for below staticLayout background color as transperentblock to appear text clearly can some one help me how can i achieve this
Code
public static Bitmap drawMultilineTextToBitmap(Context gContext, Bitmap bitmap, String gText) {
// prepare canvas
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
//Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
TextPaint paint = new TextPaint(Paint.LINEAR_TEXT_FLAG|Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(false);
paint.setFilterBitmap(false);
paint.setDither(true);
paint.setColor(Color.rgb(255, 255, 255));
paint.setFakeBoldText(true);
paint.setTextSize(8);
int textWidth = canvas.getWidth() - (int) (16 * scale);
// init StaticLayout for text
StaticLayout textLayout = new StaticLayout(gText, paint,
canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f,
false);
// get height of multiline text
int textHeight = textLayout.getHeight();
// get position of text's top left corner
float x = (bitmap.getWidth() - textWidth);
float y = (bitmap.getHeight() - textHeight);
// draw text to the Canvas Left
canvas.save();
//canvas.translate(x, y);
canvas.translate((canvas.getWidth() / 2) - (textLayout.getWidth() / 2), y);
textLayout.draw(canvas);
canvas.restore();
return bitmap;
}
public static int argb (int alpha,
int red,
int green,
int blue)
Return a color-int from alpha, red, green, blue components. These component values should be , but there is no range check performed, so if they are out of range, the returned color is undefined.
so use Color.argb(0,0,0,0)
Fully transparent - "#00000000"

How to combine TextView and an image and return an image?

While searching for results I came across this
How can I convert a View to a Drawable?
The idea behind this is I can convert TextView into a bitmap first and then combine the two bitmaps. But by converting the TextView into Bitmap, it would make it lose it's transparency which I don't want. I want the TextView over my ImageView but as one image using canvas.
My idea is to create images like these:
Here I want to enclose the text with a drawable shape for that white border.
And then place this Textview on an image and then save everything as a bitmap.
Please help
You can try to draw text and lines on canvas.
Below is example method which draws text on drawable image and returns Bitmap.
You can set custom font by calling .setTypeface() on Paint object.
Call canvas.drawLine() to draw line. To customize your line you can create new Paint object, set its color and width by .setColor() and .setStrokeWidth() and pass it in drawLine() together with line coordinates.
public Bitmap drawTextOnBitmap(Context context, int resId, String text) {
// prepare canvas
Resources resources = context.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, resId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are immutable, so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialiased Paint
TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.rgb(61, 61, 61));
// text size in pixels
paint.setTextSize((int) (bitmap.getHeight() / 10 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
// set text width to canvas width minus 16dp padding
int textWidth = canvas.getWidth() - (int) (16 * scale);
// init StaticLayout for text
StaticLayout textLayout = new StaticLayout(text, paint, textWidth,
Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
// get height of multiline text
int textHeight = textLayout.getHeight();
// get position of text's top left corner
float x = (bitmap.getWidth() - textWidth) / 2;
float y = (bitmap.getHeight() - textHeight) / 2;
// draw text to the Canvas center
canvas.save();
canvas.translate(x, y);
textLayout.draw(canvas);
canvas.restore();
return bitmap;
}
Update:
To draw rectangle add this to the method:
Paint p = new Paint();
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(24);
RectF rectF = new RectF(80, 150, 200, 350);
canvas.drawRect(rectF, p);
Parameters for new RectF():
left
The X coordinate of the left side of the rectangle
top
The Y coordinate of the top of the rectangle
right
The X coordinate of the right side of the rectangle
bottom
The Y coordinate of the bottom of the rectangle

Android Drawable Marker with Bitmap Text Overlay too Small

I am creating a Marker with text but the text is showing only 3 characters and very small and it is right of the bit map image. I want the text to go across the middle of the icon and it big font. I manually increased setFontsize to larger size did not work and also drawText width and height still did not work.
private Drawable createMarkerIcon(Drawable backgroundImage, String text,
int width, int height) {
Bitmap canvasBitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888); //width, height,
// Create a canvas, that will draw on to canvasBitmap.
Canvas imageCanvas = new Canvas(canvasBitmap);
// Set up the paint for use with our Canvas
Paint imagePaint = new Paint();
imagePaint.setTextAlign(Align.CENTER);
imagePaint.setTextSize(26f); // 8f
// Draw the image to our canvas
backgroundImage.draw(imageCanvas);
// Draw the text on top of our image
imageCanvas.drawText(text, width /1, height / 1, imagePaint); //2 , 2
// Combine background and text to a LayerDrawable
LayerDrawable layerDrawable = new LayerDrawable(
new Drawable[]{backgroundImage, new BitmapDrawable(canvasBitmap)});
return layerDrawable;
}
I call this function:
d=createMarkerIcon(getResources().getDrawable(R.drawable.pointer_bubble_selected), markerTxt, 100, 100); //marker_green=23x37 29, 50
Here is the solution for the text overlay bound problem. Replace one line with all this lines:
// draw text to the Canvas center
Rect bounds = new Rect();
int x = (canvasBitmap.getWidth() - bounds.width())/2;
int y = (canvasBitmap.getHeight() + bounds.height())/2;
// Draw the text on top of our image
//imageCanvas.drawText(text, width /4, height / 4, imagePaint); //OLD
imageCanvas.drawText(text, x , y, imagePaint); //NEW

Android drawText including text wrapping

I am currently creating an image editor and am attempting to draw text on top of on image using canvas.drawText(). So far I have been successful in doing this but when the user enters text that is too long, the text just continues on one line out of the page and doesn't wrap itself to the width of the screen. How would I go about doing this? I have tried using a static layout but cannot seem to get it to work, has anyone got a tutorial to do this?
My function for drawing on a canvas using static layout:
public Bitmap createImage(float scr_x,float scr_y,String user_text){
Canvas canvas = new Canvas(image);
scr_x = 100;
scr_y = 100;
final TextPaint tp = new TextPaint(Color.WHITE);
canvas.save();
StaticLayout sl = new StaticLayout("" + user_text, tp, originalBitmap.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
sl.draw(canvas);
return image;
}
Okay, I've updated my code, but when I try to draw on the image nothing happens at all, I have no idea why either:
public Bitmap createImage(String user_text) {
// canvas object with bitmap image as constructor
Canvas canvas = new Canvas(image);
TextPaint tp = new TextPaint();
tp.setColor(Color.RED);
tp.setTextSize(50);
tp.setTextAlign(Align.CENTER);
tp.setAntiAlias(true);
StaticLayout sl = new StaticLayout("" + user_text, tp,
canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1, 0, false);
canvas.translate(100, 100);
sl.draw(canvas);
return image;
}
Is staticlayout not meant to be used to draw on canvas?
Yes, StaticLayout is what you're meant to use to draw multi-line text on a Canvas. Save yourself a world of pain and don't think about breaking text yourself -- you're on the right path.
I'm not sure about the bitmap problem, but your second code above worked just fine to draw text on a canvas for me.
Learn to use StaticLayout , then draw the Layout object onto a canvas using the Layout.draw() method.
References
public Bitmap drawMultilineTextToBitmap(Context gContext,
int gResId,
String gText) {
// prepare canvas
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialiased Paint
TextPaint paint=new TextPaint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.rgb(61, 61, 61));
// text size in pixels
paint.setTextSize((int) (14 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
// set text width to canvas width minus 16dp padding
int textWidth = canvas.getWidth() - (int) (16 * scale);
// init StaticLayout for text
StaticLayout textLayout = new StaticLayout(
gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
// get height of multiline text
int textHeight = textLayout.getHeight();
// get position of text's top left corner
float x = (bitmap.getWidth() - textWidth)/2;
float y = (bitmap.getHeight() - textHeight)/2;
// draw text to the Canvas center
canvas.save();
canvas.translate(x, y);
textLayout.draw(canvas);
canvas.restore();
return bitmap;
}
source : http://www.skoumal.net/en/android-drawing-multiline-text-on-bitmap/
You should handle it yourself, calculating the text size and wrapping the content in some way (break line at max width or wrap last word).
I already did it on Java SE with the FontMetrics, never for Android; but you should take a look:
http://developer.android.com/reference/android/graphics/Paint.FontMetrics.html
As pointed by Lisa, StaticLayout is the way to go to measure text wrapping.

Center text on a bitmap

I'm trying to draw a text on the center of a bitmap however I can't do it even though I used align.center. The code is:
public Bitmap drawTextToBitmap(Context gContext, String gText) {
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap =
BitmapFactory.decodeResource(resources, R.drawable.blank_marker);
android.graphics.Bitmap.Config bitmapConfig =
bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.rgb(61, 61, 61));
// text size in pixels
paint.setTextSize((int) (25 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.setTextAlign(Align.CENTER);
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 * scale, y * scale, paint);
return bitmap;
}
What am I doing wrong?
It's a lot more straightforward than you think.
Draw the text at half the Bitmap's width and height (center point) in combination with Paint.setTextAlign(Align.CENTER).
The alignment property will take care of the rest.
I guess none of the answers given above are good enough so I post my answer. Try it out guys, it will work on all devices and is not complex at all:
String text = "Text"; //your string
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(activity.getResources().getColor(R.color.white));
paint.setTextSize(30);
// draw text to the Canvas center
Rect boundsText = new Rect();
paint.getTextBounds(text, 0, text.length(), boundsText);
int x = (bitmap.getWidth() - boundsText.width()) / 2;
int y = (bitmap.getHeight() + boundsText.height()) / 2;
canvas.drawText(text, x, y, paint);
Where is the text drawing? The issue might be since you changed the text align to Align.CENTER. Your code calculating x and y assumes the text rendering is using Align.LEFT, I believe.
Either use setTextAlign(Align.CENTER) and render at the actual bitmap center, or use setTextAlign(Align.LEFT) and use the current x and y calculations you are using.

Categories

Resources