如何在图像上绘制文字?

发布于 2024-12-03 04:50:50 字数 1435 浏览 1 评论 0原文

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

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>

I want to draw text on image ( for saving that image with text ). i have image view i set bitmap to that image i want to Draw the text on image (text entered by user ). i tried this before saving.....

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 code is..

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

独享拥抱 2024-12-10 04:50:50

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

输出

在此处输入图像描述

As suggested by Vladislav Skoumal, try this method:

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

}

call this method

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

the output

enter image description here

椵侞 2024-12-10 04:50:50

更新了 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();
    }
}

让我知道这是否适合您。

沙什

Updated SaveImage() method, to support text drawing.

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

Let me know if this works for you.

Shash

鸵鸟症 2024-12-10 04:50:50

您可以扩展视图来创建自定义视图。 在ondraw方法中,

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

您可以使用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"/>

You can extend a view to create a custom view. Something like

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

In the ondraw method you can use canvas.drawBitmap and canvas.drawText to draw bitmaps and text.

This way you do not requirre a framelayout as everything is in a single custom view.

You can include this in your xml file as

<com.raj.PieView android:id="@+id/framelayout" android:layout_marginTop="30dip"      
    android:layout_height="fill_parent" android:layout_width="fill_parent"/>
泅渡 2024-12-10 04:50:50
  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); 
  1. create an empty bitmap
  2. create a new Canvas object and pass this bitmap to it
  3. call view.draw(Canvas) passing it the canvas object you just created. Refer Documentation of method for details.
  4. Use Bitmap.compress() to write the contents of the bitmap to an OutputStream, file maybe.

Pseudo code:

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); 
吖咩 2024-12-10 04:50:50

在图像上填充文本视图。
请参阅 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);

Inflate a text view over the image .
Refer http://www.android10.org/index.php/forums/43-view-layout-a-resource/715-tutorial-android-xml-view-inflation for a basic example.
This should be the easiest way.

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);
时光无声 2024-12-10 04:50:50

我解决了这个问题(不可变文件),但文件中没有写入任何内容...按照我的代码:
公共静态文件writeOnImage(文件文件)抛出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;
}

I solve this problem (immutable file), but nothing is write in file... follow my code:
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;
}
水波映月 2024-12-10 04:50:50

如果您使用 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)
            }

        })

In case you using Glide to get the image, i modified @Dwivedi's answer to this (using 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)
            }

        })
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文