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”
2. Configure the project
3. Design application launcher icon
4. Create a blank activity
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
11. Download Source Code