如何在底部的图像位图上放置文本?

how to put text on image bitmap at bottom?

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

原图

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

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

问题是什么:

  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 保持不变。即文本大小会根据不同的图像大小而变化。

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

/** * 对于水印 */

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

检查以下代码:-

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