I want to get an animated text in Android where it should run from left to right on the screen.
Eg.
I want to get this text
private static final String QUOTE =
"Nobody uses Java anymore. It's this big heavyweight ball and chain.";
running from right to left using animation.
However, this text gets truncated to "Nobody uses Java anymore. It's" in Portrait mode and to
"Nobody uses Java anymore. It's this big heavyweight" in landscape mode.
This is the code that I have used
Paint paint = new Paint();
paint.setColor(Color.BLUE);
private static final String QUOTE =
"Nobody uses Java anymore. It's this big heavyweight ball and chain.";
paint.setTextSize(20);
paint.setAntiAlias(true);
int len= QUOTE.length();
canvas.scale(1,-1);
canvas.drawText(QUOTE, 0, len-1, 100, 60, paint);
canvas.drawText(QUOTE,0,100 , paint);
createAnim(canvas);
private void createAnim(Canvas canvas) {
anim2= new TranslateAnimation(500,-500,30,30);
anim2.setRepeatCount(Animation.INFINITE);
anim2.setInterpolator(new AccelerateDecelerateInterpolator());
anim2.setRepeatMode(Animation.RESTART);
anim2.setDuration(1000L);
startAnimation(anim2);
}
How to do Text Animations using Android SDK?
Please refer this post for text animations.
Please check height and width of canvas ,
// Custom Font Text
Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
.getDefaultDisplay().getWidth(),
(int) getWindowManager().getDefaultDisplay()
.getHeight() / 2, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
drawingImageView.setImageBitmap(bitmap);
paint = new Paint();
paint.setColor(Color.BLACK);
paint.setTextSize(150);
Typeface chops = Typeface.createFromAsset(this.getAssets(),
"WC_Speed_Bold_Bta.ttf");
paint.setTypeface(chops);
int xPos = (canvas.getWidth() / 2);
int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint
.ascent()) / 2));
canvas.drawText("Hello", xPos, yPos, paint);
Related
I have been trying to make a photo sharing app, with the ability to add your image and name to the image. I have been messing with Canvas for the whole day, but couldn't get good results. I was able to draw the name and bitmap, but they didn't look so good.
That's why I am here asking about is there any library or piece of code that could help me in making something similar to [this][1]. I wasn't able to find any thing for it.
EDIT: Sorry for not adding my own code
Here is my code from my latest try
public void AddText(Position2D pos){
//Position2D is an enum having the 4 corners of the image
bmWorking= bmOriginal.copy(Bitmap.Config.ARGB_8888,true);
Canvas canvas = new Canvas(bmWorking);
Paint paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
Paint textPaint = new Paint();
textPaint.setColor(Color.BLACK);
float width = (35f/100f) * bmWorking.getWidth();
float height = (width/16f) * 3;
textPaint.setTextSize(height - 4); //I wanted to have some space (margin) above and below the text
textPaint.setTextAlign(Paint.Align.LEFT);
float [] coords = getPositionCoords(pos, width, height); //getPositionCoords returns a float array with the Left,Top,Right,Bottom position calculated based on the width and height
canvas.drawRect(coords[0],coords[1], coords[2], coords[3],paint);
username = "Haider Ali Punjabi";
canvas.drawText(username, coords[0] ,coords[3], textPaint);
bitmapView.setImageBitmap(bmWorking);
}
Here is the result
UPDATE:
#pskink gave me this code
which works nicely
if you want to customize it, then instead of solid white rectangle (like in your original code) use a Drawable and the result could be something like this:
the code:
// for int gravity: see android.view.Gravity, like Gravity.LEFT, Gravity.BOTTOM, etc
// for example:
// Bitmap out = addText(this, in, "Haider Ali Punjabi", android.R.drawable.alert_light_frame, Gravity.BOTTOM, new Point(10, 10));
public Bitmap addText(Context ctx, Bitmap in, String text, int resId, int gravity, Point pad) {
if (pad == null) pad = new Point();
Bitmap out = in.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(out);
Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
textPaint.setColor(Color.BLACK);
textPaint.setTextAlign(Paint.Align.LEFT);
// textPaint.setTextSize(128);
Rect inBounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), inBounds);
float scale = out.getWidth() * 0.35f / inBounds.width();
Rect container = new Rect(0, 0, out.getWidth(), out.getHeight());
Rect outBounds = new Rect();
int w = (int) (inBounds.width() * scale);
int h = (int) (inBounds.height() * scale);
Gravity.apply(gravity, 2 * pad.x + w, 2 * pad.y + h, container, outBounds);
Drawable dr = ctx.getResources().getDrawable(resId);
Rect padding = new Rect();
dr.getPadding(padding);
dr.setBounds(outBounds.left - padding.left, outBounds.top - padding.top, outBounds.right + padding.right, outBounds.bottom + padding.bottom);
dr.draw(canvas);
Matrix matrix = new Matrix();
RectF src = new RectF(inBounds);
RectF dst = new RectF(outBounds);
dst.inset(pad.x, pad.y);
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
canvas.concat(matrix);
canvas.drawText(text, 0, 0, textPaint);
return out;
}
Im using camera in my android app but I have to add text to save captured image (after capturing image app should ask to add text to save captured image). How can I do this ?
What I think you are trying to do is to save a note with the image.
You should create a directory in which you will save the image with say name "image****.jpg". In the same directory create a file with same name but with different extension on no extension at all. (like "image****.txt").
When you access the image file, open the note file seperately and process it.
Try this to write text to bitmap from camera...
private Bitmap writeTextBitmap(Bitmap bitmap,String text) {
Typeface tf = Typeface.create("Helvetica", Typeface.BOLD);
Paint paint = new Paint();
paint.setStyle(Style.FILL);
paint.setColor(Color.WHITE);
paint.setTypeface(tf);
paint.setTextAlign(Align.CENTER);
paint.setTextSize(20);
Rect textRect = new Rect();
paint.getTextBounds(text, 0, text.length(), textRect);
Canvas canvas = new Canvas(bitmap);
//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) - 2; //-2 is for regulating the x position offset
//"- ((paint.descent() + paint.ascent()) / 2)" is the distance from the baseline to the center.
int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;
canvas.drawText(text, xPos, yPos, paint);
return bitmap;
}
I want to use custom markers on google maps in my Android app.
For this I have a method, which creates me Bitmaps. Each Bitmap is a marker including special text on it.
I have done this and it works ok on my 2.3.3 Android. But on other devices it crashes, cause I dont use mutable Bitmaps.
I changed my code to mutable Bitmaps, but now the text isn't visible, just the marker bitmap without text.
My method:
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), R.drawable.marker);
Typeface tf = Typeface.create("Helvetica", Typeface.BOLD);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTypeface(tf);
paint.setTextAlign(Paint.Align.CENTER);
paint.setTextSize(convertToPixels(context, 8));
Rect textRect = new Rect();
paint.getTextBounds(markerText, 0, markerText.length(), textRect);
// THIS LINE IS NEW FOR MUTABLE
Bitmap mutableBitmap = bm.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
if(textRect.width() >= (canvas.getWidth() - 4)){
paint.setTextSize(convertToPixels(context, 7));
}
int xPos = (canvas.getWidth() / 2) - 2;
int yPos = (int) ((canvas.getHeight() / 2) - ((paint.descent() + paint.ascent()) / 2)) ;
canvas.drawText(markerText, xPos, yPos, paint);
return bm;
What I am doing wrong? I just add the line with mutable.
best regards
Your method returns the immutable bitmap that you obtained using BitmapFactory.decodeResource().
You must return the mutable bitmap you drawed on:
return mutableBitmap;
I am creating a drawing tool, where user add text to image. While making the text draw to bitmap via canvas position is not being set properly.
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setTypeface(tf);
paint.setTextAlign(Paint.Align.LEFT);
paint.setTextSize(30);
int xPos = layoutTextViewContainer.getLeft();
int yPos = layoutTextViewContainer.getTop();
canvas.drawText(text, xPos, yPos, paint);
Paint
Rect textRect = new Rect();
paint.getTextBounds(text, 0, text.length(), textRect);
textRect.offset(0, -textRect.top);
Canvas canvas = new Canvas(bm);
layoutTextViewContainer holds the edit text.
Screen shot for more clarification.
Black text is written and Red text is preview of embed in image
Got the solution. the values should be pixel independent
convert xPos and yPos as below before passing to drawText
xPos = (int) (xPos / getResources().getDisplayMetrics().density);
yPos = (int) (yPos / getResources().getDisplayMetrics().density);
Its even better to use Drawing cache and save that to any file location.
In this case we dont have to much bother about positioning.
Wrap all in one layout and get the
view.getDrawingCache()
How to draw a filled rectangle with specified bounds and inside that rectangle text to be drawn using Canvas Android ?? I tried
mPaint.setColor(Color.GREEN);
canvas.drawText(mText, x, y, mPaint);
mPaint.setColor(Color.BLACK);
canvas.drawRect(x, y, x + w, y + h, mPaint);
but text is not inside of that rectangle. Can any buddy tell me how to draw a rectangle surrounding specified text with consideration of text size ??
Here i have hardcoded x and y values. You can change them
mpaint= new Paint();
mpaint.setColor(Color.RED);
mpaint.setStyle(Style.FILL);
paint2= new Paint();
paint2.setColor(Color.GREEN);
paint2.setTextSize(50); //set text size
float w = paint2.measureText(s)/2;
float textSize = paint2.getTextSize();
#Override
protected void onDraw(Canvas canvas) {
paint2.setTextAlign(Paint.Align.CENTER);
canvas.drawRect(300-w, 300 - textsize, 300 + w, 300, mpaint);
canvas.drawText(s, 300, 300 ,paint2); //x=300,y=300
}
Edit :
Its bad a idea to call measureText in onDraw. You can do that outside of onDraw.
There is a video on also about performance and why you should avoid allocations in onDraw. https://www.youtube.com/watch?v=HAK5acHQ53E
Resulting snap shot
If you have to center the text inside de rect you have use this code
mpaint= new Paint();
mpaint.setColor(Color.RED);
mpaint.setStyle(Style.FILL);
paint2= new Paint();
paint2.setColor(Color.GREEN);
paint2.setTextSize(50); //set text size
float w = paint2.measureText(s)/2;
float textSize = paint2.getTextSize();
#Override
protected void onDraw(Canvas canvas) {
paint2.setTextAlign(Paint.Align.CENTER);
Rect rect = new Rect(300-w, 300 - textsize, 300 + w, 300);
canvas.drawRect(rect, mpaint);
canvas.drawText(s, rect.centerX(), rect.centerY() ,paint2); // center text inside rect
}
This might be very late for this particular query but I think many will find this answer useful. So, the problem with the Canvas for any CustomView is that, you can get the width for a particular text, but it's not that easy to get the height of the text. Also if you are using canvas.drawText(....) with simple Paint object, you can not draw multi line text. So, use the below code within your onDraw() method.
String displayText = "Hello World";
int mainTextPositionX = getWidth() / 2 ;
int mainTextPositionY = getHeight() / 2;
StaticLayout textStaticLayout;
TextPaint textPaint;
textPaint = new TextPaint();
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setColor(Color.BLUE);
textPaint.setAntiAlias(true);
textPaint.setTextSize(convertDpToPixel(30, context));
textPaint.setTextAlign(Paint.Align.CENTER);
highlightedRectPaint = new Paint();
highlightedRectPaint.setStrokeWidth(12);
highlightedRectPaint.setStyle(Paint.Style.STROKE);
highlightedRectPaint.setColor(Color.RED);
highlightedRectPaint.setAntiAlias(true);
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
textStaticLayout = StaticLayout
.Builder
.obtain(displayText, 0, displayText.length(), textPaint, (int) textPaint.measureText(displayText))
.build();
}else{
textStaticLayout = new StaticLayout(
displayText, textPaint, (int)textPaint.measureText(displayText), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
}
Rect highlightedTextBorderRect = new Rect();
highlightedTextBorderRect.top = mainTextPositionY-20;
highlightedTextBorderRect.left = mainTextPositionX-
((int)textPaint.measureText(displayText)/2)-20;
highlightedTextBorderRect.right = mainTextPositionX+
((int)textPaint.measureText(displayText)/2) + 20;
highlightedTextBorderRect.bottom = mainTextPositionY+
(int)textStaticLayout.getHeight()+20;
canvas.save();
canvas.translate(mainTextPositionX, mainTextPositionY);
textStaticLayout.draw(canvas);
canvas.restore();
canvas.drawRect(highlightedTextBorderRect,highlightedRectPaint);
just make sure that, you declare all the objects and variable outside of the draw() method. And this will draw a rectangle outline around the text with multi line support. If you want the rectangle to have a fill, then just use the highlightedRectPaint and change the setStyle(Paint.Style.FILL). Hope that helps.