【问题标题】:how to put text on image bitmap at bottom?如何在底部的图像位图上放置文本?
【发布时间】:2019-01-05 18:42:33
【问题描述】:

我想要什么:我想在从图库或相机中选择的图像底部添加文本。

原图

我在底部的图像中添加了蓝色条

在那条带中,我想在中间添加一些文本。

有什么问题:

  1. 我无法将文本准确地定位在蓝色条带的中间。
  2. 对于不同的图像,文本大小会发生变化。有时它很小,有时它很大。

我尝试了什么:我的代码如下所示。

MainActivity.java

    public class MainActivity extends AppCompatActivity {

    private ImageView mImageView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageView = findViewById(R.id.imageView);
    }

    public void openGallery(View view) {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), 100);
    }

    public void openCamera(View view) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, 101);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (data != null && resultCode == Activity.RESULT_OK) {

            if (requestCode == 100) {

                Bitmap bitmap = null;
                try {
                    bitmap = MediaStore.Images.Media
                            .getBitmap(getApplicationContext().getContentResolver(), data.getData());
                } catch (IOException e) {
                    e.printStackTrace();
                }

                addStampToImage(bitmap);

            } else if (requestCode == 101) {

                Bitmap bitmap = (Bitmap) data.getExtras().get("data");
                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes);
                File destination = new File(Environment.getExternalStorageDirectory(),
                        System.currentTimeMillis() + ".jpg");
                FileOutputStream fo;
                try {
                    destination.createNewFile();
                    fo = new FileOutputStream(destination);
                    fo.write(bytes.toByteArray());
                    fo.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                addStampToImage(bitmap);
            }
        }
    }

    private void addStampToImage(Bitmap originalBitmap) {

        int extraHeight = (int) (originalBitmap.getHeight() * 0.15);

        Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
                originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);

        Canvas canvas = new Canvas(newBitmap);
        canvas.drawColor(Color.BLUE);
        canvas.drawBitmap(originalBitmap, 0, 0, null);

        Resources resources = getResources();
        float scale = resources.getDisplayMetrics().density;

        Paint pText = new Paint();
        pText.setColor(Color.WHITE);
        pText.setTextSize((int) (20 * scale));

        String text = "Maulik";

        /*Rect r = new Rect();
        canvas.getClipBounds(r);
        int cHeight = r.height();
        int cWidth = r.width();
        pText.setTextAlign(Paint.Align.LEFT);
        pText.getTextBounds(text, 0, text.length(), r);
        float x = -r.left;
        float y = cHeight / 2f + r.height() / 2f - r.bottom;

        int minusSpace = (int) (canvas.getClipBounds().bottom * 0.07);

        canvas.drawText(text, 0, canvas.getClipBounds().bottom - minusSpace, pText);*/

        Rect bounds = new Rect();
        pText.getTextBounds(text, 0, text.length(), bounds);
        int x = (newBitmap.getWidth() - bounds.width())/6;
        int y = (newBitmap.getHeight() + bounds.height())/5;

        canvas.drawText(text, x * scale, y * scale, pText);

        mImageView.setImageBitmap(newBitmap);
    }
}

任何帮助将不胜感激!

更新日期:2018 年 8 月 1 日

addStampToImage 方法的变化。

int extraHeight = (int) (originalBitmap.getHeight() * 0.15);

Rect textHeightWidth = new Rect();
pText.getTextBounds(fromWhichMode, 0, fromWhichMode.length(), textHeightWidth);

canvas.drawText(textToStamp, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
                originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
                pText);

以上更改在蓝色条带的中间给了我文字。但核心 ISSUE 保持不变。即文本大小会根据不同的图像大小而变化。

【问题讨论】:

  • 你的位图宽度和高度是动态变化还是只改变宽度还是只改变高度?
  • 是的,它会改变。这取决于我通过 Gallery 或 **Camera**@Nainal 选择的图像
  • 您是否能够正确放置文本,即位于蓝色条带的中心。正如我检查了您的代码并且它没有将文本放置在正确的位置?
  • 是的。我能。我会更新问题。
  • @Nainal 我更新了问题。

标签: android canvas android-imageview android-canvas android-bitmap


【解决方案1】:

试试这个我觉得对你有帮助

/** * 对于水印 */

public static Bitmap waterMark(Bitmap src, String watermark, Point location, int color, int alpha, int size, boolean underline) {
            int[] pixels = new int[100];

            //get source image width and height
            int widthSreen = src.getWidth();   // 1080L // 1920
            int heightScreen = src.getHeight();  // 1343L  // 2387


            Bitmap result = Bitmap.createBitmap(widthSreen, heightScreen, src.getConfig());
            //create canvas object
            Canvas canvas = new Canvas(result);
            //draw bitmap on canvas
            canvas.drawBitmap(src, 0, 0, null);
            //create paint object
            Paint paint = new Paint();
    //        //apply color
    //        paint.setColor(color);
    //        //set transparency
    //        paint.setAlpha(alpha);
    //        //set text size
            size = ((widthSreen * 5) / 100);
            paint.setTextSize(size);
    //        paint.setAntiAlias(true);
    //        //set should be underlined or not
    //        paint.setUnderlineText(underline);
    //
    //        //draw text on given location
    //        //canvas.drawText(watermark, w / 4, h / 2, paint);

            Paint.FontMetrics fm = new Paint.FontMetrics();
            paint.setColor(Color.WHITE);
    //        paint.setTextSize(18.0f);
            paint.getFontMetrics(fm);
            int margin = 5;
            canvas.drawRect(50 - margin, 50 + fm.top - margin,
                    50 + paint.measureText(watermark) + margin, 50 + fm.bottom
                            + margin, paint);

            paint.setColor(Color.RED);
            canvas.drawText(watermark, 50, 50, paint);
            return result;
        }

在你的 onActivityResult 上调用这个方法

 Bitmap bitmapp = waterMark(bitmap, your_string, p, Color.RED, 90, 90, true);

【讨论】:

  • 让我检查一下。顺便说一句,谢谢。
  • 您的代码也遇到了同样的问题。如果图像大小不同,文本大小会发生变化@Saif
  • 然后您可以设置固定大小或文本:更改这 2 行:size = 40; \\或者你想要的任何大小paint.setTextSize(size);
  • 你说的是,我已经试过了。我想你没有得到我的问题。可以再参考一下吗?对于不同大小的图像,写在图像上的文字应该看起来相同大小@Saif
  • @MaulikDodia 我这边同样的问题有什么想法吗?
【解决方案2】:

检查以下代码:-

private void addStampToImage(Bitmap originalBitmap) {

    int extraHeight = (int) (originalBitmap.getHeight() * 0.15);

    Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
            originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(newBitmap);
    canvas.drawColor(Color.BLUE);
    canvas.drawBitmap(originalBitmap, 0, 0, null);

    Resources resources = getResources();
    float scale = resources.getDisplayMetrics().density;

    String text = "Maulik";
    Paint pText = new Paint();
    pText.setColor(Color.WHITE);

    setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);




    Rect bounds = new Rect();
    pText.getTextBounds(text, 0, text.length(), bounds);

    int x=  ((newBitmap.getWidth()-(int)pText.measureText(text))/2);
    int h=(extraHeight+bounds.height())/2;
    int y=(originalBitmap.getHeight()+h);

    canvas.drawText(text, x, y, pText);

    imageView.setImageBitmap(newBitmap);
}


private void setTextSizeForWidth(Paint paint, float desiredHeight,
                                        String text) {

    // Pick a reasonably large value for the test. Larger values produce
    // more accurate results, but may cause problems with hardware
    // acceleration. But there are workarounds for that, too; refer to
    // http://stackoverflow.com/questions/6253528/font-size-too-large-to-fit-in-cache
    final float testTextSize = 48f;

    // Get the bounds of the text, using our testTextSize.
    paint.setTextSize(testTextSize);
    Rect bounds = new Rect();
    paint.getTextBounds(text, 0, text.length(), bounds);

    // Calculate the desired size as a proportion of our testTextSize.
    float desiredTextSize = testTextSize * desiredHeight / bounds.height();

    // Set the paint for that size.
    paint.setTextSize(desiredTextSize);
}

编辑:- 除了上面的 addStampToImage 方法,您还可以使用更新后的 addStampToImage 方法,如下所示:-

private void addStampToImage(Bitmap originalBitmap) {

    int extraHeight = (int) (originalBitmap.getHeight() * 0.15);

    Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(),
            originalBitmap.getHeight() + extraHeight, Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(newBitmap);
    canvas.drawColor(Color.BLUE);
    canvas.drawBitmap(originalBitmap, 0, 0, null);

    Resources resources = getResources();
    float scale = resources.getDisplayMetrics().density;

    String text = "Maulik";
    Paint pText = new Paint();
    pText.setColor(Color.WHITE);

    setTextSizeForWidth(pText,(int) (originalBitmap.getHeight() * 0.10),text);


    Rect bounds = new Rect();
    pText.getTextBounds(text, 0, text.length(), bounds);

    Rect textHeightWidth = new Rect();
    pText.getTextBounds(text, 0, text.length(), textHeightWidth);

    canvas.drawText(text, (canvas.getWidth() / 2) - (textHeightWidth.width() / 2),
            originalBitmap.getHeight() + (extraHeight / 2) + (textHeightWidth.height() / 2),
            pText);

    imageView.setImageBitmap(newBitmap);
}

【讨论】:

  • 让我检查一下,我会回复你的。
  • 看起来很棒。让我也检查一下其他图像。谢谢。
  • @MaulikDodia 好的
猜你喜欢
  • 2019-01-07
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 1970-01-01
  • 2015-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多