Add text to image in android programmatically
Asked Answered
G

4

14

I want to make an application just like opening screen of android.I am dynamically adding images to the rows of tableLayout. I have only defined tableLayout in xml file and remaining code is in java. I have added images successfully but i am not getting any help with setting text of that image (I want to display a text under image) and image to be a specific padding.How to do it?Thanks in advance.

Global answered 19/6, 2012 at 11:58 Comment(1)
I suggest you to use GridView.Correct
S
11

What you can instead do is to put a TextView in overlay to a ImageView using a RelativeLayout :)

Sulphuric answered 19/6, 2012 at 12:21 Comment(1)
Yes.I have done it now.I managed to add FrameLayout in Table rows and it worked fine.Thanks all.Global
B
37

Use the following function to write Text on Images:

private BitmapDrawable writeTextOnDrawable(int drawableId, String text) {

    Bitmap bm = BitmapFactory.decodeResource(getResources(), drawableId)
            .copy(Bitmap.Config.ARGB_8888, true);

    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(convertToPixels(mContext, 11));

    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) - 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 new BitmapDrawable(getResources(), bm);
}



public static int convertToPixels(Context context, int nDP)
{
    final float conversionScale = context.getResources().getDisplayMetrics().density;

    return (int) ((nDP * conversionScale) + 0.5f) ;

}
Bethesde answered 19/6, 2012 at 12:8 Comment(6)
How to add a bold text on bitmap ? is there an options? plz guide me.Garda
your method worked for me except for the text size. I had to set the text size (x5) your value to be readable in my icon drawable. this could be due to the conversion Scale for my device. thanks!Heavenly
what i the mContext here?Kuenlun
@Arun George I used above code in my project. It worked. But one small problem is that the size of a bitmap image is very large up to 4MB which is stored on SD card after using this function. But I need up to 1 MB or less than that. Will you please guide me for this. And Thanks for above codeParakeet
getting NullPointerException at Bitmap.copy method. Please suggestLiberty
here is KOTLIN version of this codeAirla
S
11

What you can instead do is to put a TextView in overlay to a ImageView using a RelativeLayout :)

Sulphuric answered 19/6, 2012 at 12:21 Comment(1)
Yes.I have done it now.I managed to add FrameLayout in Table rows and it worked fine.Thanks all.Global
A
4

Here's Kotlin version Arun's solution:

import org.jetbrains.anko.dip

fun Context.writeTextOnDrawable(drawableId: Int, text: String) =
        DrawableUtil.writeTextOnDrawableInternal(this, drawableId, text, 25, -2, 0)

object DrawableUtil {

    fun writeTextOnDrawableInternal(context: Context, drawableId: Int, text: String,
            textSizeDp: Int, horizontalOffset: Int, verticalOffset: Int): BitmapDrawable {

        val bm = BitmapFactory.decodeResource(context.resources, drawableId)
                .copy(Bitmap.Config.ARGB_8888, true)

        val tf = Typeface.create("Helvetica", Typeface.BOLD)

        val paint = Paint()
        paint.style = Paint.Style.FILL
        paint.color = Color.WHITE
        paint.typeface = tf
        paint.textAlign = Paint.Align.LEFT
        paint.textSize = context.dip(textSizeDp).toFloat()

        val textRect = Rect()
        paint.getTextBounds(text, 0, text.length, textRect)

        val canvas = 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.textSize = context.dip(12).toFloat()

        //Calculate the positions
        val xPos = canvas.width.toFloat()/2 + horizontalOffset  

        //"- ((paint.descent() + paint.ascent()) / 2)" is the distance from the baseline to the center.
        val yPos = (canvas.height / 2 - (paint.descent() + paint.ascent()) / 2) + verticalOffset

        canvas.drawText(text, xPos, yPos, paint)

        return BitmapDrawable(context.resources, bm)
    }
}
Airla answered 16/9, 2018 at 17:21 Comment(0)
A
3

I m successfully implemented such problem of adding text on image. Just look at following code. First of take one view as Relative layout in that layout take ImageView after that EditText and after that button. Give each of a id. Write a loadBitmapFromView function below.

public Bitmap loadBitmapFromView(View v) {
        Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
        v.draw(c);
        return b;
    }

and on click of button.

               Bitmap bitmap = loadBitmapFromView(relativeLayout);
                File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(),         "folderName");
                if (!dir.exists())
                    dir.mkdirs();

                File file = new File(dir, "capture.jpg");
                try {
                    FileOutputStream fos = new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                    imageView.setImageBitmap(bitmap);    
                } catch (Exception e) {
                    Log.e("ExpressionEditImageActivity", "Error, " + e);
                }

Enjoy...

For more reference, refer below screenshot: enter image description here

Athanasia answered 26/9, 2014 at 17:17 Comment(3)
thanks for this nice solution. can you help please with the line of code ` Bitmap bitmap = loadBitmapFromView(relativeLayout)` I am not able to get a reference to relativeLayout ... if i give ID of RelativeLayout it doesn't accept it. Can you please explain a little. ThanksPigmentation
Pass your parent view, In my case, it's relative layout.Athanasia
well.. i m not able to visualize this. could you please explain a little more with some sample code.. thanks!Pigmentation

© 2022 - 2024 — McMap. All rights reserved.