将绘图从自定义视图保存到 SD 卡 android

saving drawing to sdcard from a custom view android

我正在开发一个可以在自定义视图上绘制的应用程序。我想用一个按钮保存绘图。我在其他线程上尝试了其他解决方案,但没有。请用下面的方法给我一个例子。实际上,这不是我的方法。来自 https://github.com/msiuts/FingerPaint

自定义视图
DrawView.java

public class DrawView extends View implements OnTouchListener {

private static final String TAG = "DrawView";

private final Random random = new Random();

private final int[] colors = new int[] {Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK,
        Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK};

private final Paint paint = new Paint();

private Path path = new Path();

private Canvas canvas;
private Bitmap bitmap;

// deletes the screen by painting it black when the Menu Button is pressed
// this is a good method but how about save the drawing?
private OnKeyListener clearingOnKeyListener = new OnKeyListener() {
    public boolean onKey(View view, int i, KeyEvent keyEvent) {
        if (KeyEvent.KEYCODE_MENU == keyEvent.getKeyCode() && KeyEvent.ACTION_DOWN == keyEvent.getAction()) {
            bitmap.eraseColor(Color.BLACK);
            invalidate();
            return true;
        }
        return false;
    }
};


public DrawView(Context context, AttributeSet attrs) {
    super(context, attrs);
    setFocusable(true);
    setFocusableInTouchMode(true);

    this.setOnTouchListener(this);
    this.setOnKeyListener(clearingOnKeyListener);

    paint.setColor(randomColor());
    paint.setAntiAlias(true);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(3f);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    if (bitmap != null) {
        if (bitmap.getHeight() == w && bitmap.getWidth() == h) {
            Log.d(TAG, "rotating bitmap by 90 degree");

            Matrix mtx = new Matrix();
            mtx.postRotate(90, h/2, w/2);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, h, w, mtx, false);
            canvas = new Canvas();
            canvas.setBitmap(bitmap);
            return;
        } else {
            bitmap.recycle();
        }
    }
    canvas = new Canvas();
    bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    canvas.setBitmap(bitmap);

}

@Override
public void onDraw(Canvas c) {
    // draw to the screen
    c.drawBitmap(bitmap, null, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), null);
}

public boolean onTouch(View view, MotionEvent event) {
    // draw the new Points to our internal canvas / bitmap
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        paint.setColor(randomColor());
        path = new Path();
        path.moveTo(event.getX(), event.getY());
    } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
        int historySize = event.getHistorySize();
        for (int i=0; i < historySize; i++) {
            path.lineTo(event.getHistoricalX(i), event.getHistoricalY(i));
        }
        path.lineTo(event.getX(), event.getY());
        canvas.drawPath(path, paint);
    } else {
        return super.onTouchEvent(event);
    }
    invalidate();
    return true;
}


public Bitmap getBitmap() {
    return bitmap;
}

public void initBitmap(Bitmap bmap) {
    bitmap = bmap;
}


/**
 * Chooses a random color.
 * @return the chosen color
 */
private int randomColor() {
    return colors[random.nextInt(colors.length)];
}
}

Activity
绘图 Activity.java

public class DrawingActivity extends Activity {
private static final String TAG = "FingerPaint";

private DrawView drawView;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_draw);

    // restore view
    drawView = (DrawView) findViewById(R.id.drawView);
    Log.d(TAG, "DrawView from R is null? " + (drawView == null));
    Bitmap lastDrawing = (Bitmap) getLastNonConfigurationInstance();
    if (lastDrawing != null) {
        Log.d(TAG, "lastDrawing is not null");

        drawView.initBitmap(lastDrawing);
    }
}


@Override
public Object onRetainNonConfigurationInstance() {
    Bitmap bmap = null;
    if (drawView != null) {
        bmap = drawView.getBitmap();
        Log.d(TAG, "onRetainNonConfigurationInstance returning a bitmap: " + (bmap != null));

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

假设您想将文件保存到设备存储,这是我使用的解决方案...

添加清单权限: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

这是我的做法:

// Variables i needed
private String mFileName;
private Bitmap mBitmap;


  // apply this listener to your button
  private final View.OnClickListener ButtonListener = new View.OnCickListener(){
       @Override
        public void onClick(View v){
          new SaveFile().execute();
      }
 }


   private class SaveFile extends AsyncTask<Void, Void, File>{
    @Override
    protected File doInBackground(Void... params) {

        View rootView = findViewById(R.id.drawView);
        File newBackgroundBitmap  = saveFileToStorage(rootView);

        return newBackgroundBitmap;
    }

    @Override
    protected void onPostExecute(File bitmapFile) {
        super.onPostExecute(bitmapFile);
        if(bitmapFile != null){
         Toast.makeText(getBaseContext(), "Saved drawView to storage", Toast.LENGTH_SHORT).show();
       }

    }
}

那么这是完成所有工作的方法:

/**
 * Saves the Bitmap File to Storage and returns the new File
 * @param rootView - the View we want to capture
 * @return returns the new FileName of the image.
 */
private File saveFileToStorage(View rootView){

    rootView.setDrawingCacheEnabled(true);

    mBitmap = rootView.getDrawingCache();

    File fileDirectory = new File(Environment.getExternalStorageDirectory() + "FOLDER_NAME_YOU_WANT_TO_USE");
    fileDirectory.mkdirs();

    // Filename to store, Probably want to add some time stamp to make this unique
    mFileName = "YOUR_FILE_NAME"+ ".png";
   final File newBackgroundBitmap = new File(fileDirectory, mFileName);

    try{
        newBackgroundBitmap.createNewFile();
        FileOutputStream outputStream = new FileOutputStream(newBackgroundBitmap);
        mBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
        outputStream.close();

        Log.d(TAG, "File saved..." + " " + mFileName);
    }catch(Exception e){
        e.printStackTrace();
    }

    return newBackgroundBitmap;
}