Android App - How To Save A Bitmap Drawing On Canvas As Image? Check Code?
I tried to use the following codes to Draw on canvas Save the canvas on Image Problem - When I try to save the image, it shows a null pointer error and nothing is saved. Please
Solution 1:
MyDrawView
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.LruCache;
import android.view.MotionEvent;
import android.view.View;
publicclassMyDrawViewextendsView {
public Bitmap mBitmap;
public Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private Paint mPaint;
publicMyDrawView(Context c, AttributeSet attrs) {
super(c, attrs);
mPath = newPath();
mBitmapPaint = newPaint(Paint.DITHER_FLAG);
mPaint = newPaint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFF000000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(9);
}
@OverrideprotectedvoidonSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = newCanvas(mBitmap);
}
@OverrideprotectedvoidonDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
privatefloat mX, mY;
privatestaticfinalfloatTOUCH_TOLERANCE=4;
privatevoidtouch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
privatevoidtouch_move(float x, float y) {
floatdx= Math.abs(x - mX);
floatdy= Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
mX = x;
mY = y;
}
}
privatevoidtouch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
@OverridepublicbooleanonTouchEvent(MotionEvent event) {
floatx= event.getX();
floaty= event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
returntrue;
}
public Bitmap getBitmap()
{
//this.measure(100, 100);//this.layout(0, 0, 100, 100);this.setDrawingCacheEnabled(true);
this.buildDrawingCache();
Bitmapbmp= Bitmap.createBitmap(this.getDrawingCache());
this.setDrawingCacheEnabled(false);
return bmp;
}
publicvoidclear(){
mBitmap.eraseColor(Color.GREEN);
invalidate();
System.gc();
}
}
MainActivity
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.View;
import android.view.View.MeasureSpec;
import android.widget.Button;
import android.widget.Toast;
publicclassMainActivityextendsActivity
{
MyDrawView myDrawView;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// myDrawView = new MyDrawView(this, null);
setContentView(R.layout.activity_main);
myDrawView = (MyDrawView)findViewById(R.id.draw);
Buttonbutton1= (Button)findViewById(R.id.button1);
button1.setOnClickListener(newView.OnClickListener()
{
publicvoidonClick(View v)
{
Filefolder=newFile(Environment.getExternalStorageDirectory().toString());
booleansuccess=false;
if (!folder.exists())
{
success = folder.mkdirs();
}
System.out.println(success+"folder");
Filefile=newFile(Environment.getExternalStorageDirectory().toString() + "/sample.png");
if ( !file.exists() )
{
try {
success = file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(success+"file");
FileOutputStreamostream=null;
try
{
ostream = newFileOutputStream(file);
System.out.println(ostream);
ViewtargetView= myDrawView;
// myDrawView.setDrawingCacheEnabled(true);// Bitmap save = Bitmap.createBitmap(myDrawView.getDrawingCache());// myDrawView.setDrawingCacheEnabled(false);// copy this bitmap otherwise distroying the cache will destroy// the bitmap for the referencing drawable and you'll not// get the captured view// Bitmap save = b1.copy(Bitmap.Config.ARGB_8888, false);//BitmapDrawable d = new BitmapDrawable(b);//canvasView.setBackgroundDrawable(d);// myDrawView.destroyDrawingCache();// Bitmap save = myDrawView.getBitmapFromMemCache("0");// myDrawView.setDrawingCacheEnabled(true);//Bitmap save = myDrawView.getDrawingCache(false);Bitmapwell= myDrawView.getBitmap();
Bitmapsave= Bitmap.createBitmap(320, 480, Config.ARGB_8888);
Paintpaint=newPaint();
paint.setColor(Color.WHITE);
Canvasnow=newCanvas(save);
now.drawRect(newRect(0,0,320,480), paint);
now.drawBitmap(well, newRect(0,0,well.getWidth(),well.getHeight()), newRect(0,0,320,480), null);
// Canvas now = new Canvas(save);//myDrawView.layout(0, 0, 100, 100);//myDrawView.draw(now);if(save == null) {
System.out.println("NULL bitmap save\n");
}
save.compress(Bitmap.CompressFormat.PNG, 100, ostream);
//bitmap.compress(Bitmap.CompressFormat.PNG, 100, ostream);//ostream.flush();//ostream.close();
}catch (NullPointerException e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Null error", Toast.LENGTH_SHORT).show();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "File error", Toast.LENGTH_SHORT).show();
}
catch (IOException e)
{
e.printStackTrace();
Toast.makeText(getApplicationContext(), "IO error", Toast.LENGTH_SHORT).show();
}
}
});
}
@OverridepublicbooleanonCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
returntrue;
}
}
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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.example.draw2.MyDrawView
android:id ="@+id/draw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"></com.example.draw2.MyDrawView>"
<Button
android:id ="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="save"
android:layout_alignParentBottom="true"
></Button>"
</RelativeLayout>
and in your AndroidManifest.xml make sure you have
<?xml version="1.0" encoding="utf-8"?><manifestxmlns:android="http://schemas.android.com/apk/res/android"package="com.example.draw2"android:versionCode="1"android:versionName="1.0" ><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="17" /><uses-permissionandroid:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme" ><activityandroid:name="com.example.draw2.MainActivity"android:label="@string/app_name" ><intent-filter><actionandroid:name="android.intent.action.MAIN" /><categoryandroid:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>
Solution 2:
There is a little add on in the above code. The above code is saving the pic in the storage. But the Image is not showing in the gallery. To show the image in gallery just need to setup a MediaScannerConnection
for the bitmap we are saving
Sample Function
publicvoidscanPhoto(final String imageFileName) {
MediaScannerConnection msConn = newMediaScannerConnection(PaintPic.this,
newMediaScannerConnectionClient() {
publicvoidonMediaScannerConnected() {
msConn.scanFile(imageFileName, null);
Log.i("msClient obj in Photo Utility",
"connection established");
}
publicvoidonScanCompleted(String path, Uri uri) {
msConn.disconnect();
Log.i("msClient obj in Photo Utility", "scan completed");
}
});
msConn.connect();
}
and call this function just after this line
save.compress(Bitmap.CompressFormat.PNG, 100, ostream);
Now the saved bitmap is also visible in the Gallery
Post a Comment for "Android App - How To Save A Bitmap Drawing On Canvas As Image? Check Code?"