Get the canvas bitmap of custom View


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.

Get the canvas bitmap of custom View


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();

}

}


0 Response to "Get the canvas bitmap of custom View"

Posting Komentar