4

What I Want: I want to add text at bottom of a image which I have chose from either gallery or camera.

Original Image

Original Image

I added blue color strip to image at bottom

I added little strip to image at bottom

In that strip, I want to add some text exactly in middle.

What's the Problem:

  1. I'm unable to position text exactly in middle of blue color strip.
  2. For different images, text size changes. Some time it is very small, some time it is very big.

What I Tried: My code is like below.

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

Any help will be appreciated!

Updated: 1st Aug 2018

Changes in addStampToImage method.

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

Above changes giving me text in middle of blue strip. But core ISSUE remains same. i.e Text size changes with respect to different image sizes.

Maulik Dodia
  • 1,629
  • 2
  • 21
  • 48

2 Answers2

4

Check the below code:-

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

Edit:- Instead of above addStampToImage method you can also use your updated addStampToImage method like below:-

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);
}
Nainal
  • 1,728
  • 14
  • 27
0

try this one i think help to you

/** * FOR WATER-MARK */

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

call this method on your onActivityResult

 Bitmap bitmapp = waterMark(bitmap, your_string, p, Color.RED, 90, 90, true);
Saif
  • 723
  • 6
  • 21