Android App - How to save a bitmap drawing on canvas as image? Check code?

前端 未结 2 1455
攒了一身酷
攒了一身酷 2021-02-04 12:46

I tried to use the following codes to

  1. Draw on canvas
  2. Save the canvas on Image

Problem - When I try to save the image, it shows a null

相关标签:
2条回答
  • 2021-02-04 12:58

    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>
    
    0 讨论(0)
  • 2021-02-04 13:00

    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

    public void scanPhoto(final String imageFileName) {
        MediaScannerConnection msConn = new MediaScannerConnection(PaintPic.this,
                new MediaScannerConnectionClient() {
                    public void onMediaScannerConnected() {
                        msConn.scanFile(imageFileName, null);
                        Log.i("msClient obj  in Photo Utility",
                                "connection established");
                    }
    
                    public void onScanCompleted(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

    0 讨论(0)
提交回复
热议问题