在Android中以编程方式向图像添加文本

14

我希望制作一个类似于Android开机界面的应用程序。我正在动态向TableLayout的行中添加图片。我只在XML文件中定义了TableLayout,其余代码都在Java中。我已经成功地添加了图片,但是我没有得到任何有关设置图片下方文本(我想在图像下方显示文本)和为图片设置特定填充的帮助。如何做到这一点?谢谢。


1
我建议您使用GridView。 - Krishna Suthar
4个回答

37

使用以下函数在图片上写入文本:

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) ;

}

如何在位图上添加粗体文本?有什么选项吗?请指导我。 - Sampath Kumar
你的方法对我有用,但是文本大小不适合我。我不得不将你的值设置为(x5)以便在我的图标中可读。这可能是由于我的设备比例转换造成的。谢谢! - droideckar
3
这里的mContext是什么? - Nitesh Verma
@Arun George,我在我的项目中使用了上述代码。它有效果。但是有一个小问题,就是使用此函数后,位图图像的大小非常大,高达4MB,存储在SD卡上。但我需要1MB或更少的空间。请问您能否为我提供指导?感谢您提供的代码。 - Kailas Bhakade
在 Bitmap.copy 方法中出现了 NullPointerException,请提供建议。 - Uma Achanta
1
这是Kotlin版本的代码:here - kosiara - Bartosz Kosarzycki

11
你可以使用 RelativeLayout 将 TextView 放置在 ImageView 的上层,从而实现效果 :)

是的,我现在已经完成了。我成功地在表格行中添加了FrameLayout,并且它运行良好。谢谢大家。 - dka72

4
这是 Kotlin 版本的 Arun 的解决方案:

请查看此处


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)
    }
}

3

我成功地实现了在图片上添加文本的问题。只需要看以下代码。首先,将一个视图作为相对布局,然后在该布局中放置ImageView,然后是EditText和button。为每个元素分配一个id。写一个loadBitmapFromView函数如下。

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;
    }

当点击按钮时。

               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);
                }

欢迎使用...

更多参考,请查看下面的截图: enter image description here


谢谢您提供这个好的解决方案。您能帮忙解释一下代码行Bitmap bitmap = loadBitmapFromView(relativeLayout)吗?我无法获取对relativeLayout的引用...如果我给出RelativeLayout的ID,它不会接受它。您能否详细说明一下。谢谢。 - Nikhil G
1
传递你的父视图,我的情况下是相对布局。 - Ganesh Katikar
嗯...我无法想象这个。你能否用一些示例代码再解释一下?谢谢! - Nikhil G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接