Monday, August 19, 2013

Draw text on bitmap using Canvas.drawText()

Example to draw text on bitmap using Canvas.drawText() method.

Draw text on bitmap using Canvas.drawText()


package com.example.androiddrawtextonbitmap;

import java.io.FileNotFoundException;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Bitmap.Config;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
 
 Button btnLoadImage1;
 TextView textSource1;
 EditText editTextCaption;
 Button btnProcessing;
 ImageView imageResult;
 
 final int RQS_IMAGE1 = 1;
 
 Uri source1;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  
  btnLoadImage1 = (Button)findViewById(R.id.loadimage1);
  textSource1 = (TextView)findViewById(R.id.sourceuri1);
  editTextCaption = (EditText)findViewById(R.id.caption);
  btnProcessing = (Button)findViewById(R.id.processing);
  imageResult = (ImageView)findViewById(R.id.result);
  
  btnLoadImage1.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View arg0) {
    Intent intent = new Intent(Intent.ACTION_PICK,
      android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
    startActivityForResult(intent, RQS_IMAGE1);
   }});
  
  btnProcessing.setOnClickListener(new OnClickListener(){

   @Override
   public void onClick(View v) {
    
    if(source1 != null){
     Bitmap processedBitmap = ProcessingBitmap();
     if(processedBitmap != null){
      imageResult.setImageBitmap(processedBitmap);
      Toast.makeText(getApplicationContext(), 
        "Done", 
        Toast.LENGTH_LONG).show();
     }else{
      Toast.makeText(getApplicationContext(), 
        "Something wrong in processing!", 
        Toast.LENGTH_LONG).show();
     }
    }else{
     Toast.makeText(getApplicationContext(), 
       "Select both image!", 
       Toast.LENGTH_LONG).show();
    }
    
   }});
 }
 
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if(resultCode == RESULT_OK){
   switch (requestCode){
   case RQS_IMAGE1:
    source1 = data.getData();
    textSource1.setText(source1.toString());
    break;
   }
  }
 }
 
 private Bitmap ProcessingBitmap(){
  Bitmap bm1 = null;
  Bitmap newBitmap = null;
  
  try {
   bm1 = BitmapFactory.decodeStream(
     getContentResolver().openInputStream(source1));
   
   Config config = bm1.getConfig();
   if(config == null){
    config = Bitmap.Config.ARGB_8888;
   }
   
   newBitmap = Bitmap.createBitmap(bm1.getWidth(), bm1.getHeight(), config);
   Canvas newCanvas = new Canvas(newBitmap);
   
   newCanvas.drawBitmap(bm1, 0, 0, null);
   
   String captionString = editTextCaption.getText().toString();
   if(captionString != null){
    
    Paint paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
    paintText.setColor(Color.BLUE);
    paintText.setTextSize(50);
    paintText.setStyle(Style.FILL);
    paintText.setShadowLayer(10f, 10f, 10f, Color.BLACK);
    
    Rect rectText = new Rect();
    paintText.getTextBounds(captionString, 0, captionString.length(), rectText);
    
    newCanvas.drawText(captionString, 
      0, rectText.height(), paintText);
    
    Toast.makeText(getApplicationContext(), 
      "drawText: " + captionString, 
      Toast.LENGTH_LONG).show();
    
   }else{
    Toast.makeText(getApplicationContext(), 
      "caption empty!", 
      Toast.LENGTH_LONG).show();
   }
   
  } catch (FileNotFoundException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  
  return newBitmap;
 }

}


Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold"
        android:layout_gravity="center_horizontal"
        android:autoLink="web" />

    <Button
        android:id="@+id/loadimage1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load Image 1" />
    <TextView
        android:id="@+id/sourceuri1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/caption"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/processing"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Draw text on Bitmap" />
    <ImageView
        android:id="@+id/result"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
</LinearLayout>


download filesDownload the files.

If you simple want to display TextView over ImageView only, refer to next exercise.


more: Something about processing images in Android


Updated@2015-01-03:

Tested on Nexus 7 2012 running Android 4.4.4. (without permission of "android.permission.READ_EXTERNAL_STORAGE")


Anyway, if you fail to load the bitmap from storage on Android 4.4 or above, try to add permission of "android.permission.READ_EXTERNAL_STORAGE". Refer Update "android.permission.READ_EXTERNAL_STORAGE" for KitKat.

8 comments:

Anonymous said...

Thanks a ton .... your piece of code helped me alot :)

nik viradiya said...

This Is Not Working In 4.4

Andr.oid Eric said...

Hello nik viradiya,

Tested again on Nexus 7 running Android 4.4.4. check the video in the post.

Anyway, if you fail to load the bitmap from storage on Android 4.4 or above, try to add permission of "android.permission.READ_EXTERNAL_STORAGE". Refer Update "android.permission.READ_EXTERNAL_STORAGE" for KitKat.

Ashish said...

hi , i wann save that watermark images in gallery so how can i save it ?

Andr.oid Eric said...

hello Ashish,

please check Open image, free draw something on bitmap, and save bitmap to ExternalStorage.

Anonymous said...

I want to draw text at exact locations on different screens. how do i do it?

Tanvi Thakkar said...

hello Ashish,

I draw text on image. But i want to move text on image view.How it is possible.if u know please help me.Thanks in advance.

Anonymous said...

how to set width wrap and move to next line for long text ?