Android应用程序 - 如何保存一个位图在画布上的图像绘制?检查code?位图、画布、应用程序、图像

2023-09-13 00:27:00 作者:他是神话她是童话我是笑话

我试图用下面的codeS到

在画在画布上 保存在画布上的图像

问题 - 当我试图保存图片,它显示了一个空指针错误,并没有什么保存的

请帮我找到了code中的问题或建议我另一种选择,这确实excatly相同。先谢谢了。

code画在画布上:

 包com.example.draw2;

进口android.content.Context;
进口android.graphics.Bitmap;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.Paint;
进口android.graphics.Path;
进口android.util.AttributeSet;
进口android.view.MotionEvent;
进口android.view.View;

公共类MyDrawView扩展视图{
    私人位图mBitmap;
    私人帆布mCanvas;
    私人路径的mpath;
    私人油漆mBitmapPaint;
    私人油漆mPaint;

    公共MyDrawView(上下文C,AttributeSet中的ATTRS){
        超级(C,ATTRS);

        的mpath =新路径();
        mBitmapPaint =新的油漆(Paint.DITHER_FLAG);

        mPaint =新的油漆();
        mPaint.setAntiAlias​​(真正的);
        mPaint.setDither(真正的);
        mPaint.setColor(0xFF000000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap​​(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(9);
    }


    @覆盖
    保护无效onSizeChanged(INT W,INT小时,INT oldw,诠释oldh){
        super.onSizeChanged(W,H,oldw,oldh);
        mBitmap = Bitmap.createBitmap(W,H,Bitmap.Config.ARGB_8888);
        mCanvas =新的Canvas(mBitmap);
    }

    @覆盖
    保护无效的OnDraw(帆布油画){
        canvas.drawBitmap(mBitmap,0,0,mBitmapPaint);

        canvas.drawPath(的mpath,mPaint);


    }

    私人浮动MX,我的;
    私有静态最终浮动TOUCH_TOLERANCE = 4;

    私人无效touch_start(浮X,浮动Y){
        mPath.reset();
        mPath.moveTo(X,Y);
        MX = X;
        我= Y;
    }
    私人无效TOUCH_MOVE(浮X,浮动Y){
        浮DX = Math.abs(X  -  MX);
        浮DY = Math.abs(Y  - 我的);
        如果(DX> = TOUCH_TOLERANCE || DY> = TOUCH_TOLERANCE){
            mPath.quadTo(MX,MY,(X + MX)/ 2,(Y +我)/ 2);
            MX = X;
            我= Y;
        }
    }
    私人无效touch_up(){
        mPath.lineTo(MX,MY);
        //提交路径,我们的屏幕外
        mCanvas.drawPath(的mpath,mPaint);
        //杀了这个,所以我们不重复抽奖
        mPath.reset();
    }

    @覆盖
    公共布尔的onTouchEvent(MotionEvent事件){
        浮X = event.getX();
        浮动Y = event.getY();

        开关(event.getAction()){
            案例MotionEvent.ACTION_DOWN:
                touch_start(X,Y​​);
                无效();
                打破;
            案例MotionEvent.ACTION_MOVE:
                TOUCH_MOVE(X,Y);
                无效();
                打破;
            案例MotionEvent.ACTION_UP:
                润色();
                无效();
                打破;
        }
        返回true;
    }

    公共位图getBitmap()
    {
    返回mBitmap;
    }



    公共无效清除(){
        mBitmap.eraseColor(Color.GREEN);
        无效();
        System.gc()的;

    }

}
 

二code保存画布图像是主要活动。

我尝试了一些东西,的code某些部分是注释。

由于我是初学者,我AP preciate任何意见

二code MainActivity:

 包com.example.draw2;

进口的java.io.File;
进口java.io.FileNotFoundException;
进口java.io.FileOutputStream中;
进口java.io.IOException异常;

进口android.app.Activity;
进口android.graphics.Bitmap;
进口android.os.Bundle;
进口android.os.Environment;
进口android.view.Menu;
进口android.view.View;
进口android.widget.Button;
进口android.widget.Toast;


公共类MainActivity扩展活动
{
    MyDrawView myDrawView;


    @覆盖
    保护无效的onCreate(包savedInstanceState)
    {

        super.onCreate(savedInstanceState);
        myDrawView =新MyDrawView(这一点,NULL);
        的setContentView(R.layout.activity_main);

        按钮按钮1 =(按钮)findViewById(R.id.button1);
        button1.setOnClickListener(新View.OnClickListener()
        {
            公共无效的onClick(视图v)
            {
                //查看内容= myDrawView;

                //System.out.println(content);


                //位图位= content.getDrawingCache();

                文件夹=新的文件(Environment.getExternalStorageDirectory()的toString());
                 布尔成功= FALSE;
                 如果(!folder.exists())
                 {
                     成功= folder.mkdirs();
                 }

                 的System.out.println(成功+文件夹);

                 档案文件=新的文件(Environment.getExternalStorageDirectory()的toString()+/sample.JPEG。);

             如果(!file.exists())
             {
                   尝试 {
                    成功= file.createNewFile();
                }赶上(IOException异常E){
                    e.printStackTrace();
                }
             }

             的System.out.println(成功+文件);



             FileOutputStream中的ostream = NULL;
                尝试
                {
                ostream的=新的FileOutputStream(文件);

                的System.out.println(ostream的);

                位图保存= myDrawView.getBitmap();
                如果(救== NULL){
                    的System.out.println(NULL位图保存的\ n);
                }
                save.com preSS(Bitmap.Com pressFormat.PNG,100,ostream的);
                //bitmap.com$p$pss(Bitmap.Com$p$pssFormat.PNG,100,ostream的);
                   ostream.flush();
                    ostream.close();
                }赶上(NullPointerException异常E)
                {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),空错误,Toast.LENGTH_SHORT).show();
                }

                赶上(FileNotFoundException异常E)
                {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),文件错误,Toast.LENGTH_SHORT).show();
                }

                赶上(IOException异常E)
                {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),IO错误,Toast.LENGTH_SHORT).show();
                }

            }
        });

    }


    @覆盖
    公共布尔onCreateOptionsMenu(功能菜单){
        //充气菜单;这增加了项目操作栏,如果它是present。
        。getMenuInflater()膨胀(R.menu.main,菜单);
        返回true;
    }
}
 
Android应用签名

解决方案

MyDrawView

 进口android.annotation.Sup pressLint;
进口android.content.Context;
进口android.graphics.Bitmap;
进口android.graphics.Bitmap.Config;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.Paint;
进口android.graphics.Path;
进口android.graphics.Rect;
进口android.util.AttributeSet;
进口android.util.LruCache;
进口android.view.MotionEvent;
进口android.view.View;

公共类MyDrawView扩展视图{
    公共位图mBitmap;
    公共帆布mCanvas;
    私人路径的mpath;
    私人油漆mBitmapPaint;
    私人油漆mPaint;


    公共MyDrawView(上下文C,AttributeSet中的ATTRS){
        超级(C,ATTRS);

        的mpath =新路径();
        mBitmapPaint =新的油漆(Paint.DITHER_FLAG);

        mPaint =新的油漆();
        mPaint.setAntiAlias​​(真正的);
        mPaint.setDither(真正的);
        mPaint.setColor(0xFF000000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap​​(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(9);

    }


    @覆盖
    保护无效onSizeChanged(INT W,INT小时,INT oldw,诠释oldh){
        super.onSizeChanged(W,H,oldw,oldh);
        mBitmap = Bitmap.createBitmap(W,H,Bitmap.Config.ARGB_8888);
        mCanvas =新的Canvas(mBitmap);
    }

    @覆盖
    保护无效的OnDraw(帆布油画){
        canvas.drawBitmap(mBitmap,0,0,mBitmapPaint);

        canvas.drawPath(的mpath,mPaint);


    }

    私人浮动MX,我的;
    私有静态最终浮动TOUCH_TOLERANCE = 4;

    私人无效touch_start(浮X,浮动Y){
        mPath.reset();
        mPath.moveTo(X,Y);
        MX = X;
        我= Y;
    }
    私人无效TOUCH_MOVE(浮X,浮动Y){
        浮DX = Math.abs(X  -  MX);
        浮DY = Math.abs(Y  - 我的);
        如果(DX> = TOUCH_TOLERANCE || DY> = TOUCH_TOLERANCE){
            mPath.quadTo(MX,MY,(X + MX)/ 2,(Y +我)/ 2);
            MX = X;
            我= Y;
        }
    }
    私人无效touch_up(){
        mPath.lineTo(MX,MY);
        //提交路径,我们的屏幕外
        mCanvas.drawPath(的mpath,mPaint);
        //杀了这个,所以我们不重复抽奖
        mPath.reset();
    }

    @覆盖
    公共布尔的onTouchEvent(MotionEvent事件){
        浮X = event.getX();
        浮动Y = event.getY();

        开关(event.getAction()){
            案例MotionEvent.ACTION_DOWN:
                touch_start(X,Y​​);
                无效();
                打破;
            案例MotionEvent.ACTION_MOVE:
                TOUCH_MOVE(X,Y);
                无效();
                打破;
            案例MotionEvent.ACTION_UP:
                润色();
                无效();
                打破;
        }
        返回true;
    }

    公共位图getBitmap()
    {
        //this.measure(100,100);
        //this.layout(0,0,100,100);
        this.setDrawingCacheEnabled(真正的);
        this.buildDrawingCache();
       BMP位= Bitmap.createBitmap(this.getDrawingCache());
        this.setDrawingCacheEnabled(假);


    返回BMP;
    }



    公共无效清除(){
        mBitmap.eraseColor(Color.GREEN);
        无效();
        System.gc()的;

    }

}
 

MainActivity

 进口的java.io.File;
进口java.io.FileNotFoundException;
进口java.io.FileOutputStream中;
进口java.io.IOException异常;

进口android.app.Activity;
进口android.graphics.Bitmap;
进口android.graphics.Bitmap.Config;
进口android.graphics.Canvas;
进口android.graphics.Color;
进口android.graphics.Paint;
进口android.graphics.Rect;
进口android.graphics.drawable.BitmapDrawable;
进口android.os.Bundle;
进口android.os.Environment;
进口android.view.Menu;
进口android.view.View;
进口android.view.View.MeasureSpec;
进口android.widget.Button;
进口android.widget.Toast;


公共类MainActivity扩展活动
{
    MyDrawView myDrawView;


    @覆盖
    保护无效的onCreate(包savedInstanceState)
    {

        super.onCreate(savedInstanceState);
       // myDrawView =新MyDrawView(这一点,NULL);
        的setContentView(R.layout.activity_main);
        myDrawView =(MyDrawView)findViewById(R.id.draw);
        按钮按钮1 =(按钮)findViewById(R.id.button1);
        button1.setOnClickListener(新View.OnClickListener()
        {
            公共无效的onClick(视图v)
            {


                文件夹=新的文件(Environment.getExternalStorageDirectory()的toString());
                 布尔成功= FALSE;
                 如果(!folder.exists())
                 {
                     成功= folder.mkdirs();
                 }

                 的System.out.println(成功+文件夹);

                 档案文件=新的文件(Environment.getExternalStorageDirectory()的toString()+/sample.png);

             如果(!file.exists())
             {
                   尝试 {
                    成功= file.createNewFile();
                }赶上(IOException异常E){
                    e.printStackTrace();
                }
             }

             的System.out.println(成功+文件);



             FileOutputStream中的ostream = NULL;
                尝试
                {
                ostream的=新的FileOutputStream(文件);

                的System.out.println(ostream的);
                查看=的TargetView myDrawView;

               // myDrawView.setDrawingCacheEnabled(真正的);
               //位图保存= Bitmap.createBitmap(myDrawView.getDrawingCache());
               // myDrawView.setDrawingCacheEnabled(假);
                //复制此位,否则distroying缓存会破坏
                //位图的引用可绘制,你会不会
                //获取所捕获的观点
               //位图保存= b1.copy(Bitmap.Config.ARGB_8888,假);
                // BitmapDrawable D =新BitmapDrawable(B);
                //canvasView.setBackgroundDrawable(d);
               // myDrawView.destroyDrawingCache();
               //位图保存= myDrawView.getBitmapFromMemCache(0);
               // myDrawView.setDrawingCacheEnabled(真正的);
               //位图保存= myDrawView.getDrawingCache(假);
                位图以及= myDrawView.getBitmap();
                位图保存= Bitmap.createBitmap(320,480,Config.ARGB_8888);
                涂料粉刷=新的油漆();
                paint.setColor(Color.WHITE);
                帆布现在=新的Canvas(保存);
                now.drawRect(新的矩形(0,0,320,480),油漆);
                now.drawBitmap(当然,新的矩形(0,0,well.getWidth(),well.getHeight()),新的矩形(0,0,320,480),NULL);

              //帆布现在=新的Canvas(保存);
               //myDrawView.layout(0,0,100,100);
               //myDrawView.draw(now);
                如果(救== NULL){
                    的System.out.println(NULL位图保存的\ n);
                }
                save.com preSS(Bitmap.Com pressFormat.PNG,100,ostream的);
                //bitmap.com$p$pss(Bitmap.Com$p$pssFormat.PNG,100,ostream的);
                   //ostream.flush();
                    //ostream.close();
                }赶上(NullPointerException异常E)
                {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),空错误,Toast.LENGTH_SHORT).show();
                }

                赶上(FileNotFoundException异常E)
                {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),文件错误,Toast.LENGTH_SHORT).show();
                }

                赶上(IOException异常E)
                {
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(),IO错误,Toast.LENGTH_SHORT).show();
                }

            }
        });

    }


    @覆盖
    公共布尔onCreateOptionsMenu(功能菜单){
        //充气菜单;这增加了项目操作栏,如果它是present。
        。getMenuInflater()膨胀(R.menu.main,菜单);
        返回true;
    }
}
 

activity_main.xml

 < RelativeLayout的的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    的xmlns:工具=htt​​p://schemas.android.com/tool​​s
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:paddingBottom会=@扪/ activity_vertical_margin
    机器人:以下属性来=@扪/ activity_horizo​​ntal_margin
    机器人:paddingRight =@扪/ activity_horizo​​ntal_margin
    机器人:paddingTop =@扪/ activity_vertical_margin
    工具:上下文=MainActivity。>
< com.example.draw2.MyDrawView
    机器人:ID =@ + ID /画
    机器人:layout_width =WRAP_CONTENT
    机器人:layout_height =WRAP_CONTENT>< /com.example.draw2.MyDrawView>
   <按钮
       机器人:ID =@ + ID /按钮1
       机器人:layout_width =WRAP_CONTENT
       机器人:layout_height =WRAP_CONTENT
       机器人:文本=拯救
       机器人:layout_alignParentBottom =真
       >< /按钮>中

< / RelativeLayout的>
 

和你的Andr​​oidManifest.xml请确保您有

 < XML版本=1.0编码=UTF-8&GT?;
<舱单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    包=com.example.draw2
    安卓版code =1
    机器人:VERSIONNAME =1.0>

    <用途-SDK
        安卓的minSdkVersion =8
        机器人:targetSdkVersion =17/>
    <使用-权限的Andr​​oid:名称=android.permission.READ_EXTERNAL_STORAG​​E/>
    <使用-权限的Andr​​oid:名称=android.permission.WRITE_EXTERNAL_STORAG​​E/>

    <应用
        机器人:allowBackup =真
        机器人:图标=@可绘制/ ic_launcher
        机器人:标签=@字符串/ APP_NAME
        机器人:主题=@风格/ AppTheme>
        <活动
            机器人:名称=com.example.draw2.MainActivity
            机器人:标签=@字符串/ APP_NAME>
            <意向滤光器>
                <作用机器人:名称=android.intent.action.MAIN/>

                <类机器人:名称=android.intent.category.LAUNCHER/>
            &所述; /意图滤光器>
        < /活性GT;
    < /用途>

< /舱单>
 

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 help me to find the problem with the code or suggest me an alternative, which does excatly the same. Thanks in advance.

Code to draw on canvas:

package com.example.draw2;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyDrawView extends View {
    private Bitmap  mBitmap;
    private Canvas  mCanvas;
    private Path    mPath;
    private Paint   mBitmapPaint;
    private Paint   mPaint;

    public MyDrawView(Context c, AttributeSet attrs) {
        super(c, attrs);

        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);

        mPaint = new Paint();
        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);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, mPaint);


    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = 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;
        }
    }
    private void touch_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();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = 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;
        }
        return true;
    }

    public Bitmap getBitmap()
    {
    return mBitmap;
    }



    public void clear(){
        mBitmap.eraseColor(Color.GREEN);
        invalidate();
        System.gc();

    }

}

Second code to save the canvas as image is in main activity.

I tried a few things and some part of the code is commented.

Since I am a beginner, I appreciate any advice

Second code MainActivity:

package com.example.draw2;

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.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


public class MainActivity extends Activity 
{
    MyDrawView myDrawView;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {

        super.onCreate(savedInstanceState);
        myDrawView = new MyDrawView(this, null);
        setContentView(R.layout.activity_main);

        Button button1 = (Button)findViewById(R.id.button1);    
        button1.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View v)
            {       
                //View content = myDrawView;

                //System.out.println(content);


                //Bitmap bitmap = content.getDrawingCache();

                File folder = new File(Environment.getExternalStorageDirectory().toString());
                 boolean success = false;
                 if (!folder.exists()) 
                 {
                     success = folder.mkdirs();
                 }

                 System.out.println(success+"folder");

                 File file = new File(Environment.getExternalStorageDirectory().toString() + "/sample.JPEG");

             if ( !file.exists() )
             {
                   try {
                    success = file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
             }

             System.out.println(success+"file");



             FileOutputStream ostream = null;
                try
                {
                ostream = new FileOutputStream(file);

                System.out.println(ostream);

                Bitmap save = myDrawView.getBitmap();
                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();
                }

            }
        });

    }


    @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;
    }
}

解决方案

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;

public class MyDrawView extends View {
    public Bitmap  mBitmap;
    public Canvas  mCanvas;
    private Path    mPath;
    private Paint   mBitmapPaint;
    private Paint   mPaint;


    public MyDrawView(Context c, AttributeSet attrs) {
        super(c, attrs);

        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);

        mPaint = new Paint();
        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);

    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);

        canvas.drawPath(mPath, mPaint);


    }

    private float mX, mY;
    private static final float TOUCH_TOLERANCE = 4;

    private void touch_start(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
    }
    private void touch_move(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = 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;
        }
    }
    private void touch_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();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float x = event.getX();
        float y = 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;
        }
        return true;
    }

    public Bitmap getBitmap()
    {
        //this.measure(100, 100);
        //this.layout(0, 0, 100, 100);
        this.setDrawingCacheEnabled(true);  
        this.buildDrawingCache();
       Bitmap bmp = Bitmap.createBitmap(this.getDrawingCache());   
        this.setDrawingCacheEnabled(false);


    return bmp;
    }



    public void clear(){
        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;


public class MainActivity extends Activity 
{
    MyDrawView myDrawView;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {

        super.onCreate(savedInstanceState);
       // myDrawView = new MyDrawView(this, null);
        setContentView(R.layout.activity_main);
        myDrawView = (MyDrawView)findViewById(R.id.draw);
        Button button1 = (Button)findViewById(R.id.button1);    
        button1.setOnClickListener(new View.OnClickListener() 
        {
            public void onClick(View v)
            {       


                File folder = new File(Environment.getExternalStorageDirectory().toString());
                 boolean success = false;
                 if (!folder.exists()) 
                 {
                     success = folder.mkdirs();
                 }

                 System.out.println(success+"folder");

                 File file = new File(Environment.getExternalStorageDirectory().toString() + "/sample.png");

             if ( !file.exists() )
             {
                   try {
                    success = file.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
             }

             System.out.println(success+"file");



             FileOutputStream ostream = null;
                try
                {
                ostream = new FileOutputStream(file);

                System.out.println(ostream);
                View targetView = 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);
                Bitmap well = myDrawView.getBitmap();
                Bitmap save = Bitmap.createBitmap(320, 480, Config.ARGB_8888);
                Paint paint = new Paint();
                paint.setColor(Color.WHITE);
                Canvas now = new Canvas(save);
                now.drawRect(new Rect(0,0,320,480), paint);
                now.drawBitmap(well, new Rect(0,0,well.getWidth(),well.getHeight()), new Rect(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();
                }

            }
        });

    }


    @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;
    }
}

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"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.draw2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.draw2.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>