【问题标题】:How to draw text On image?如何在图像上绘制文本?
【发布时间】:2011-11-11 08:00:07
【问题描述】:

我想在图像上绘制文本(用于保存带有文本的图像)。我有图像视图我将位图设置为我想在图像上绘制文本(用户输入的文本)的图像。我在保存之前试过这个.....

void saveImage() {
    File myDir=new File("/sdcard/saved_images");
    myDir.mkdirs();
    Random generator = new Random();
    int n = 10000;
    n = generator.nextInt(n);
    String fname = "Image-"+ n +".jpg";
    File file = new File (myDir, fname);
    if (file.exists ()) file.delete (); 
    try {
           FileOutputStream out = new FileOutputStream(file);
           originalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
           out.flush();
           out.close();

    } catch (Exception e) {
           e.printStackTrace();
    }
}

Xml 代码是..

<FrameLayout 
     android:id="@+id/framelayout"
     android:layout_marginTop="30dip"
     android:layout_height="fill_parent" 
     android:layout_width="fill_parent">

     <ImageView 
          android:id="@+id/ImageView01"
          android:layout_alignParentTop="true"
          android:layout_height="wrap_content" 
          android:layout_width="wrap_content"/>

     <TextView android:id="@+id/text_view2"
          android:layout_marginTop="20dip"
          android:layout_width="wrap_content" 
          android:text="SampleText"
          android:textSize="12pt"
          android:layout_alignTop="@+id/ImageView01" 
          android:layout_height="wrap_content"/>  

</FrameLayout>

【问题讨论】:

  • 你的问题到底是什么?你是不能画文字还是不能用文字保存图片?
  • 我的问题是我想在图片上添加文字。

标签: android image text save


【解决方案1】:

作为suggested by Vladislav Skoumal,试试这个方法:

public Bitmap drawTextToBitmap(Context mContext,  int resourceId,  String mText) {
    try {
         Resources resources = mContext.getResources();
         float scale = resources.getDisplayMetrics().density;
         Bitmap bitmap = BitmapFactory.decodeResource(resources, resourceId);
         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(110,110, 110));
         // text size in pixels
         paint.setTextSize((int) (12 * scale));
         // text shadow
         paint.setShadowLayer(1f, 0f, 1f, Color.DKGRAY);

         // draw text to the Canvas center
         Rect bounds = new Rect();
         paint.getTextBounds(mText, 0, mText.length(), bounds);
         int x = (bitmap.getWidth() - bounds.width())/6;
         int y = (bitmap.getHeight() + bounds.height())/5;

         canvas.drawText(mText, x * scale, y * scale, paint);

         return bitmap;
    } catch (Exception e) {
        // TODO: handle exception

        return null;
    }

}

调用这个方法

Bitmap bmp =drawTextToBitmap(this,R.drawable.aa,"Hello Android");
img.setImageBitmap(bmp);

输出

【讨论】:

  • @Ruhollahツ 我在 4 年前发布了这个答案,现在有多个库可用于处理图像。
  • @DwivediJi 嗨,您能分享一下这些库的名称吗?
  • @DwivediJi,这种方法存在一个问题。如果图像尺寸较小,则在图像上绘制的文本会放大。但是,如果图像尺寸很大,则文本会缩小。更多详情请参阅此stackoverflow.com/questions/69578026/…
【解决方案2】:

更新 SaveImage() 方法,支持文本绘制。

void saveImage() {
    File myDir=new File("/sdcard/saved_images");
    myDir.mkdirs();
    Random generator = new Random();
    int n = 10000;
    n = generator.nextInt(n);
    String fname = "Image-"+ n +".jpg";
    File file = new File (myDir, fname);
    if (file.exists ()) file.delete (); 
    try {
        FileOutputStream out = new FileOutputStream(file);

        // NEWLY ADDED CODE STARTS HERE [
            Canvas canvas = new Canvas(originalBitmap);

            Paint paint = new Paint();
            paint.setColor(Color.WHITE); // Text Color
            paint.setTextSize(12); // Text Size
            paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); // Text Overlapping Pattern
            // some more settings...

            canvas.drawBitmap(originalBitmap, 0, 0, paint);
            canvas.drawText("Testing...", 10, 10, paint);
        // NEWLY ADDED CODE ENDS HERE ]

        originalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();
    } catch (Exception e) {
       e.printStackTrace();
    }
}

让我知道这是否适合你。

沙士

【讨论】:

  • 它的工作非常感谢你.......经过小小的修改,我更新了答案..
  • 什么是originalBitmap?!
  • 我对这个解决方案有疑问。显示以下错误:位图是不可变的。我该如何解决?
  • 您需要将其设为可变位图。位图 mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
【解决方案3】:

您可以扩展视图以创建自定义视图。类似的东西

public class PieView extends View { 
    public PieView(Context context) {
        super(context);
        overlayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.piechart_shade, 
        null);
        overlayWidth  = overlayBitmap.getWidth();
        setLayoutParams(new LayoutParams(overlayWidth, overlayWidth));      
    }

    @Override     
    protected void onDraw(Canvas canvas) {      
        super.onDraw(canvas);
    }
}

在ondraw方法中可以使用canvas.drawBitmap和canvas.drawText来绘制位图和文字。

这样您就不需要框架布局,因为所有内容都在一个自定义视图中。

您可以将其包含在您的 xml 文件中

<com.raj.PieView android:id="@+id/framelayout" android:layout_marginTop="30dip"      
    android:layout_height="fill_parent" android:layout_width="fill_parent"/>

【讨论】:

  • 我有更多带有相关布局和按钮的 xml 代码,如何在我的代码中添加它..
【解决方案4】:
  1. 创建一个空位图
  2. 创建一个新的 Canvas 对象并将此位图传递给它
  3. 调用 view.draw(Canvas) 将您刚刚创建的画布对象传递给它。有关详细信息,请参阅方法文档。
  4. 使用 Bitmap.compress() 将位图的内容写入 OutputStream,可能是文件。

伪代码:

Bitmap  bitmap = Bitmap.createBitmap(200,200,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawText();
//necessary arguments and draw whatever you want. thes all are drawn on the bitmap.finally save this bitmap
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); 

【讨论】:

  • 我必须在哪里使用这个.. 在保存功能或 onCreate () 中。
  • 这里的view是指要绘制的view,如果要直接保存为图片则忽略view.draw(canvas);
  • 我收到强制关闭错误:java.lang.IllegalStateException:不可变位图传递给 Canvas 构造函数,修改后我的代码是:Bitmap bitmap = Bitmap.createBitmap(originalBitmap);画布画布=新画布(位图); canvas.drawText(my_text, 0, 0, null);FileOutputStream out = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
【解决方案5】:

在图像上膨胀一个文本视图。 有关基本示例,请参阅 http://www.android10.org/index.php/forums/43-view-layout-a-resource/715-tutorial-android-xml-view-inflation。 这应该是最简单的方法。

LinearLayout lLayout;

lLayout = (LinearLayout)findViewById(R.id.layout1);

layout1 is the main layout.

final LayoutInflater  inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);

TextView tv = (TextView)inflater.inflate(R.layout.text, null);

lLayout.addView(tv);

【讨论】:

  • 用文本视图替换它。在 xml 中有一个文本视图,并以与按钮相同的方式对其进行膨胀。
  • schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/dynamic_text" >您的 main.xml ......................然后将上面的代码复制并粘贴到您的 oncreate 中。用 main 替换 layout1。在字符串 s.xml 中为 dynamic_text 添加一个值
  • 添加这部分代码后出现强制关闭错误..fl = (FrameLayout) findViewById(R.id.framelayout); final LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); tv = (TextView) inflater.inflate(R.id.text_view2, null); fl.addView(tv);看我的编辑我添加了一些代码..
【解决方案6】:

我解决了这个问题(不可变文件),但文件中没有写入任何内容...按照我的代码: public static File writeOnImage(File file) throws IOException {

    Bitmap originalBitmap = BitmapFactory.decodeFile(file.getPath());
    originalBitmap = convertToMutable(originalBitmap);
    FileOutputStream out = new FileOutputStream(file);

    try {
        Canvas canvas = new Canvas(originalBitmap);

        Paint paint = new Paint();
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(12);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
        canvas.drawBitmap(originalBitmap, 0, 0, paint);
        canvas.drawText("Testing...", 10, 10, paint);

        originalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();

    } catch (Exception e) {
        e.printStackTrace();
    }

    return file;
}

【讨论】:

    【解决方案7】:

    如果您使用 Glide 获取图像,我修改了@Dwivedi 对此的回答(使用 kotlin):

    Glide.with(this)
            .asBitmap()
            .load("https://images.pexels.com/photos/1387577/pexels-photo-1387577.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260")
            .into(object : CustomTarget<Bitmap>() {
                override fun onLoadCleared(placeholder: Drawable?) {}
    
                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                    val bm = resource.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 = dip(25).toFloat()
    
                    val textRect = Rect()
                    paint.getTextBounds("HELLO WORLD", 0, "HELLO WORLD".length, textRect)
    
                    val canvas = Canvas(bm)
    
                    //If the text is bigger than the canvas , reduce the font size
                    if (textRect.width() >= canvas.width - 4)
                    //the padding on either sides is considered as 4, so as to appropriately fit in the text
                        paint.textSize = dip(12).toFloat()
    
                    //Calculate the positions
                    val xPos = canvas.width.toFloat()/2 + -2
    
                    //"- ((paint.descent() + paint.ascent()) / 2)" is the distance from the baseline to the center.
                    val yPos = (canvas.height / 2 - (paint.descent() + paint.ascent()) / 2) + 0
    
                    canvas.drawText("HELLO WORLD", xPos, yPos, paint)
    
                    binding.imageDrawable.setImageBitmap(bm)
                }
    
            })
    

    【讨论】:

      猜你喜欢
      • 2017-07-07
      • 1970-01-01
      • 2012-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多