Search code examples
javaandroidandroid-canvasdrawandroid-shape

How to draw text onto an image in Android


I have looked through countless ways of doing this but still haven't achieved the desired result; what I am trying to achieve is:

  • Draw a rectangle that is the full width of the screen and about 1/3 of the screen height where the rectangle has 50% visibility / alpha (so the image can be seen slightly underneath the rectangle) and the rectangle would be placed at the very bottom of the screen
  • Place a multi-line String within the rectangle where the text is centralised to the middle of the rectangle

Above is the basic concept that I am looking to achieve but also, if possible, I would like to generate a map that would be a small square and positioned on the left, within the rectangle - how to add this to a bitmap / canvas would also be really useful.

My current implementation (which doesn't have the correct shape or text size) can be seen below:

Bitmap bitmap = BitmapFactory.decodeByteArray(picture, 0, picture.length);
Bitmap newBitmap = ImageUtils.drawMultilineTextToBitmapV2(MainActivity.this, bitmap, imageText);

...

public static Bitmap drawMultilineTextToBitmapV2(Context context, Bitmap bitmap, String text) {

    Bitmap.Config bitmapConfig = bitmap.getConfig();

    if (bitmapConfig == null) {
        bitmapConfig = Bitmap.Config.ARGB_8888;
    }

    Bitmap alteredBitmap = bitmap.copy(bitmapConfig, true);
    Canvas canvas = new Canvas(alteredBitmap);

    // Add image to canvas
    Paint paint = new Paint();
    canvas.drawBitmap(bitmap, 0, 0, paint);

    // Add background for text
    Paint p2 = new Paint();
    p2.setStyle(Paint.Style.FILL);
    p2.setColor(Color.GRAY);
    p2.setAlpha(0x80);

   // int padding = 50;
    int padding = 1000;
    Rect rect = new Rect(
            canvas.getWidth() - padding, // Left
            canvas.getHeight() - padding, // Top
            padding, // Bottom
            canvas.getWidth() + padding // Right
    );
    canvas.drawRect(rect, p2);

    // Add text
    paint.setColor(Color.WHITE);
    paint.setTextSize(250);
    canvas.drawText(text, bitmap.getWidth(), bitmap.getHeight(), paint);

    canvas.save();
    return alteredBitmap;
}

Any help with this would be greatly appreciated.


UPDATE:

String saveFilePath = FileUtils.saveImageToInternalStorage(newBitmap, fileDirectory, fileName, dateObject);

...

The bitmap / canvas gets saved to a file so it can then be accessed again by the user.

public static String saveImageToInternalStorage(Bitmap finalBitmap, File fileDirectory, String fileName, Date date) {

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm", Locale.UK);
    String now = simpleDateFormat.format(date);

    fileDirectory = new File(fileDirectory + DCA_FILE_PATH);
    fileDirectory.mkdirs();

    if (fileName.isEmpty()) {
        DecimalFormat df = new DecimalFormat("000000");
        int i = 1;
        String startingNumber = df.format(i);
        fileName = now + "-" + startingNumber + ".jpg";
    } else {
        fileName = now + "-" + fileName + ".jpg";
    }

    File file = new File(fileDirectory, fileName);
    try {
        FileOutputStream out = new FileOutputStream(file);
        finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();

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

    Log.d(TAG, "Saving Internal File to: " + file.getAbsolutePath());
    return file.getAbsolutePath();

}

UPDATE 2:

Process of application:

  • Take photo in-app using camera view
  • Photo is returned as a byte and converted to Bitmap
  • Bitmap is converted to a canvas where the text and rectangle needs to be created and then converted back to a Bitmap
  • Bitmap is then saved as a file
  • User clicks on file to view photo which would contain the text / rectangle

Solution

  • Achieved by doing:

    public static Bitmap viewToBitmap(Activity activity, Bitmap bitmap, String mapURL, String latLong, String dateTime) {
    
        try {
    
            AsyncTask asyncTask = new BackgroundUtils.setImageFromUrl().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mapURL);
            Bitmap googleBitmap = (Bitmap) asyncTask.get();
    
            Bitmap.Config bitmapConfig = bitmap.getConfig();
    
            if (bitmapConfig == null) {
                bitmapConfig = Bitmap.Config.ARGB_8888;
            }
    
            Bitmap bmp = bitmap.copy(bitmapConfig, true);
            Canvas canvas = new Canvas(bmp);
            LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    
            ViewGroup root = (ViewGroup) activity.findViewById(R.id.relativeLayout);
            View layout = inflater.inflate(R.layout.screenshot_content, root, false);
            ImageView cameraView = (ImageView) layout.findViewById(R.id.cameraView);
            ImageView mapView = (ImageView) layout.findViewById(R.id.mapView);
            TextView latLongView = (TextView) layout.findViewById(R.id.latLongView);
            TextView dateTimeView = (TextView) layout.findViewById(R.id.dateTimeView);
    
            cameraView.setImageBitmap(bitmap);
            mapView.setImageBitmap(googleBitmap);
            latLongView.setText(latLong);
            dateTimeView.setText(dateTime);
    
            layout.setDrawingCacheEnabled(true);
            layout.measure(View.MeasureSpec.makeMeasureSpec(canvas.getWidth(), View.MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(canvas.getHeight(), View.MeasureSpec.EXACTLY));
            layout.layout(0, 0, layout.getMeasuredWidth(), layout.getMeasuredHeight());
            layout.draw(canvas);
    
            return bmp;
        } catch (Exception e) {
            e.printStackTrace();
        }
    
        return null;
    
    }