Pick an image from external application and draw in View Canvas

June 25, 2013
By

In this article, we will develop an Android application which picks up an image from an external application like Gallery, Dropbox, Google Drive etc and draw it in a view canvas.



This application is developed in Eclipse 4.2.0 with ADT Plugin (22.0.1) and Android SDK ( 22.0.1 ) .


1. Create a new Android application project namely “GraphicsPickImageViewCanvas”

Create new Android application project

Figure 1 : Create new Android application project


2. Configure the project

Configure the application project

Figure 2 : Configure the application project


3. Design application launcher icon

Design application project icon

Figure 3 : Design application launcher icon


4. Create a blank activity

Create a blank activity

Figure 4 : Create a blank activity


5. Enter MainActivity details

Enter MainActivity details

Figure 5 : Enter MainActivity details


6. Update the file res/values/strings.xml


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Pick and Draw Image</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="pick">Pick an image</string>
</resources>


7. Create a java class file src/in/wptrafficanalyzer/graphicspickimageviewcanvas/PaintView.java


package in.wptrafficanalyzer.graphicspickimageviewcanvas;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Matrix.ScaleToFit;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class PaintView extends View{

    Paint mPaint;
    Bitmap mBitmap;
    Matrix mMatrix;
    RectF mSrcRectF;
    RectF mDestRectF;
    boolean mPause;

    public PaintView(Context context,AttributeSet attributeSet){
        super(context,attributeSet);

        mPaint = new Paint();
        mMatrix = new Matrix();
        mSrcRectF = new RectF();
        mDestRectF = new RectF();
        mPause = false;
    }

    public void addBitmap(Bitmap bitmap){
        mBitmap = bitmap;
    }

    public Bitmap getBitmap(){
        return mBitmap;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(!mPause){
            if(mBitmap!=null){

                // Setting size of Source Rect
                mSrcRectF.set(0, 0,mBitmap.getWidth(),mBitmap.getHeight());

                // Setting size of Destination Rect
                mDestRectF.set(0, 0, getWidth(), getHeight());

                // Scaling the bitmap to fit the PaintView
                mMatrix.setRectToRect( mSrcRectF , mDestRectF, ScaleToFit.CENTER);

                // Drawing the bitmap in the canvas
                canvas.drawBitmap(mBitmap, mMatrix, mPaint);
            }

            // Redraw the canvas
            invalidate();
        }
    }

    // Pause or resume onDraw method
    public void pause(boolean pause){
        mPause = pause;
    }
}


8. Update the layout file res/layout/activity_main.xml


<RelativeLayout 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"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/btn_pick"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="@string/pick" />

    <in.wptrafficanalyzer.graphicspickimageviewcanvas.PaintView
        android:id="@+id/paint_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_above="@id/btn_pick" />

</RelativeLayout>

9. Update the class src/in/wptrafficanalyzer/graphicspickimageviewcanvas/MainActivity.java


package in.wptrafficanalyzer.graphicspickimageviewcanvas;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

    PaintView mPaintView;
    Button mBtnPick;
    int mWidth;
    int mHeight;

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

        mWidth = mHeight = 0;

        // Getting reference to PaintView
        mPaintView = (PaintView) findViewById(R.id.paint_view);

        // Getting reference to Button "Pick an Image"
        mBtnPick = (Button) findViewById(R.id.btn_pick);

        // Setting OnClickListener for the button
        mBtnPick.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent i = new Intent();
                i.setType("image/*");
                i.setAction(Intent.ACTION_GET_CONTENT);

                Intent customChooserIntent = Intent.createChooser(i, "Pick an image");
                startActivityForResult(customChooserIntent, 10);
            }
        });

        if(savedInstanceState!=null){
            mWidth = savedInstanceState.getInt("width");
            mHeight = savedInstanceState.getInt("height");
            Bitmap bitmap = savedInstanceState.getParcelable("bitmap");
            if(bitmap!=null){
                mPaintView.addBitmap(bitmap);
            }
        }
    }

    // Courtesy : developer.android.com/training/displaying-bitmaps/load-bitmap.html
    public static int calculateInSampleSize(

        BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            // Calculate ratios of height and width to requested height and width
            final int heightRatio = Math.round((float) height / (float) reqHeight);
            final int widthRatio = Math.round((float) width / (float) reqWidth);

            // Choose the smallest ratio as inSampleSize value, this will guarantee
            // a final image with both dimensions larger than or equal to the
            // requested height and width.
            inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
        }

        return inSampleSize;
    }

    private Bitmap getBitmapFromUri(Uri data){
        Bitmap bitmap = null;

        // Starting fetch image from file
        InputStream is=null;
        try {

            is = getContentResolver().openInputStream(data);

            // First decode with inJustDecodeBounds=true to check dimensions
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;

            // BitmapFactory.decodeFile(path, options);
            BitmapFactory.decodeStream(is, null, options);

            // Calculate inSampleSize
            options.inSampleSize = calculateInSampleSize(options, mWidth, mHeight);

            // Decode bitmap with inSampleSize set
            options.inJustDecodeBounds = false;

            is = getContentResolver().openInputStream(data);

            bitmap = BitmapFactory.decodeStream(is,null,options);

            if(bitmap==null){
                Toast.makeText(getBaseContext(), "Image is not Loaded",Toast.LENGTH_SHORT).show();
                return null;
            }

            is.close();
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }catch(NullPointerException e){
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, intent);
        if (requestCode == 10 && resultCode == RESULT_OK && null != intent) {
            Uri data = intent.getData();
            Bitmap bitmap = getBitmapFromUri(data);
            if(bitmap!=null){
                mPaintView.addBitmap(bitmap);
            }
        }
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        mWidth = mPaintView.getWidth();
        mHeight = mPaintView.getHeight();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {

        outState.putInt("width", mWidth);
        outState.putInt("height", mHeight);
        if(mPaintView.getBitmap()!=null){
            outState.putParcelable("bitmap", mPaintView.getBitmap());
        }

        super.onSaveInstanceState(outState);
    }

    @Override
    protected void onResume() {

        mPaintView.pause(false);

        // Resume repainting
        mPaintView.invalidate();

        super.onResume();
    }

    @Override
    protected void onPause() {

        // Pause repainting
        mPaintView.pause(true);

        super.onPause();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}



10. Screenshots of the application

Choose the application to pick image

Figure 6 : Choose the application to pick image

Displaying the picked image

Figure 7 : Displaying the picked image


11. Download Source Code


How to hire me?

I am George Mathew, working as software architect and Android app developer at wptrafficanalyzer.in

You can hire me on hourly basis or on project basis for Android applications development.

For hiring me, please mail your requirements to info@wptrafficanalyzer.in.

My other blogs
store4js.blogspot.com


Android Knowledge Quiz

Ready to test your knowledge in Android? Take this quiz :



Tags: , , , , ,

One Response to Pick an image from external application and draw in View Canvas

  1. Chinmay on July 10, 2015 at 8:04 pm

    Thanks for this post . Helped me in adding an image to canvas but I need to add multiple images . Every time I draw a new bitmap, the old bitmap is lost . Is there method to save current state of canvas ?

Leave a Reply

Your email address will not be published. Required fields are marked *

Be friend at g+

Subscribe for Lastest Updates

FBFPowered by ®Google Feedburner