I have a series of previous articles to draw something on custom view's canvas. All these code lose everythng after the app exit. Now I want to save the drawing in a file. In this article, I will demonstrate how to get the canvas bitmap of custom view. In next article, I will show how to save in file.
When user want to capture the canvas bitmap, touch MENU -> Capture Canvas.
I don't know why I can't get the bitmap of the custom view by getDrawingCache() as shown in the article "Capture Screen, using View.getDrawingCache()"! So I create a separated bitmap and canvas to draw on (I also used this method to solve "Flickering problems due to double buffer of SurfaceView" in former article).
- In onMeasure() of my custom view(MyView), create a bitmap(myCanvasBitmap) and canvas(myCanvas). And apply myCanvasBitmap on myCanvas.
- When I have to draw something in onDraw(), I draw on myCanvas. It will draw on myCanvasBitmap. Then apply myCanvasBitmap to the view's canvas. Also, I have to erase myCanvasBitmap on TouchEvent of MotionEvent.ACTION_DOWN.
- When I need the bitmap, when getCanvasBitmap() is called, simple return myCanvasBitmap.
The code of my custom view, MyView.java.
package com.AndroidMyCanvas; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class MyView extends View { boolean freeTouched = false; Path freePath; Bitmap myCanvasBitmap = null; Canvas myCanvas = null; Matrix identityMatrix; public MyView(Context context) { super(context); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onDraw(Canvas canvas) { if(freeTouched){ Paint paint = new Paint(); paint.setStyle(Paint.Style.STROKE); paint.setColor(Color.RED); paint.setStrokeWidth(10); myCanvas.drawPath(freePath, paint); canvas.drawBitmap(myCanvasBitmap, identityMatrix, null); } } @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_UP: freeTouched = false; break; case MotionEvent.ACTION_DOWN: freeTouched = true; freePath = new Path(); freePath.moveTo(event.getX(), event.getY()); myCanvasBitmap.eraseColor(Color.BLACK); break; case MotionEvent.ACTION_MOVE: freePath.lineTo(event.getX(), event.getY()); invalidate(); break; } return true; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int w = MeasureSpec.getSize(widthMeasureSpec); int h = MeasureSpec.getSize(heightMeasureSpec); myCanvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); myCanvas = new Canvas(); myCanvas.setBitmap(myCanvasBitmap); identityMatrix = new Matrix(); setMeasuredDimension(w, h); } public Bitmap getCanvasBitmap(){ return myCanvasBitmap; } }
Create /res/menu/menu.xml to define our option menu.
<?xml version="1.0" encoding="UTF-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/opt_capture" android:title="Capture Canvas" /> </menu>
The main code, AndroidMyCanvasActivity.java.
package com.AndroidMyCanvas; import android.app.Activity; import android.app.AlertDialog; import android.graphics.Bitmap; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.ViewGroup.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; public class AndroidMyCanvasActivity extends Activity { MyView myView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); myView = new MyView(this); setContentView(myView); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater menuInflater = getMenuInflater(); menuInflater.inflate(R.menu.menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()){ case R.id.opt_capture: openCaptureDialog(); return true; default: return false; } } private void openCaptureDialog(){ Bitmap bmMyView = myView.getCanvasBitmap(); AlertDialog.Builder captureDialog = new AlertDialog.Builder(AndroidMyCanvasActivity.this); captureDialog.setTitle("Canvas Captured"); ImageView bmImage = new ImageView(AndroidMyCanvasActivity.this); bmImage.setImageBitmap(bmMyView); LayoutParams bmImageLayoutParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); bmImage.setLayoutParams(bmImageLayoutParams); LinearLayout dialogLayout = new LinearLayout(AndroidMyCanvasActivity.this); dialogLayout.setOrientation(LinearLayout.VERTICAL); dialogLayout.addView(bmImage); captureDialog.setView(dialogLayout); captureDialog.setPositiveButton("OK", null); captureDialog.show(); } }
No comments:
Post a Comment