【问题标题】:draw on canvas without removing the background image on erase function在画布上绘制而不删除擦除功能上的背景图像
【发布时间】:2015-04-21 06:11:23
【问题描述】:

我正在尝试在图像上绘制和擦除,然后将其保存到 SD 卡。我成功绘制并将其保存到 sd 卡,但是当我检查 sd 卡中的保存图像时,我得到一个黑色背景图像而不是我绘制的图像。

请建议我如何将图像应用为画布背景并擦除绘制文本而不会丢失背景图像。我已经看到了各种堆栈溢出的例子,但我的错误是没有人为我工作,请帮助。

我需要什么:

我从 sd 卡得到什么:

这是我的努力:

public class HomeActivity extends Activity {
private Bitmap DrawBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint DrawBitmapPaint;
RelativeLayout Rl;
CustomView View;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.home);

    ActionBar actionBar = getActionBar();
    actionBar.setDisplayShowTitleEnabled(false);

    this.loadActivity();
}

private Paint mPaint;

public class CustomView extends View {

    public CustomView(Context c) {

        super(c);

        create_image();

        setLayerType(android.view.View.LAYER_TYPE_SOFTWARE, mPaint);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // mCanvas.drawColor(Color.BLUE);

        super.onSizeChanged(w, h, oldw, oldh);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        setDrawingCacheEnabled(true);
        canvas.drawBitmap(DrawBitmap, 0, 0, DrawBitmapPaint);
        canvas.drawPath(mPath, mPaint);

        canvas.drawRect(mY, 0, mY, 0, DrawBitmapPaint);
    }

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

        mCanvas.drawPath(mPath, mPaint);

        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();
            performClick();
            invalidate();
            break;
        }
        return true;
    }

    public void clear() {
        create_image();

        // Added later..
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        // mCanvas.drawColor(Color.BLUE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(12);
        this.invalidate();
    }

}

public void loadActivity() {

    View = new CustomView(this);
    Rl = (RelativeLayout) findViewById(R.id.Rel);
    Rl.addView(View);
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setDither(true);
    // mCanvas.drawColor(Color.BLUE);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setStrokeJoin(Paint.Join.ROUND);
    mPaint.setStrokeCap(Paint.Cap.ROUND);
    mPaint.setStrokeWidth(10);

}

public void create_image() {

    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    int screenWidth = displaymetrics.widthPixels;
    int screenHeight = displaymetrics.heightPixels;
    DrawBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
            Bitmap.Config.ARGB_4444);

    mCanvas = new Canvas(DrawBitmap);
    mCanvas.drawColor(R.drawable.myBackgroundImage);

    mPath = new Path();
    DrawBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.action_menu, menu);

    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    mPaint.setXfermode(null);
    switch (item.getItemId()) {
    case R.id.erase:
        mPaint.setStrokeWidth(40);

        mPaint.setColor(Color.BLUE);
        mPaint.setStrokeWidth(10);

        break;
    case R.id.DELETE:

        View.clear();
        mCanvas.drawColor(Color.BLUE);
        break;
    case R.id.color_Red:
        mPaint.setStrokeWidth(8);
        mPaint.setColor(Color.RED);

        break;
    case R.id.color_Green:
        mPaint.setStrokeWidth(8);
        mPaint.setColor(Color.GREEN);

        break;
    case R.id.color_Yello:
        mPaint.setStrokeWidth(8);
        mPaint.setColor(Color.YELLOW);

        break;

    case R.id.color_Black:
        mPaint.setStrokeWidth(8);
        mPaint.setColor(Color.BLACK);

        break;

    case R.id.draw:
        mPaint.setStrokeWidth(8);
        mPaint.setXfermode(null);

        break;

    case R.id.Save:
        String root = Environment.getExternalStorageDirectory().toString();
        File myDir = new File(root + "/saved_images");
        myDir.mkdirs();
        Random generator = new Random();
        int n = 10000;
        n = generator.nextInt(n);
        String fname = "Image-" + n + ".jpg";
        File file = new File(myDir, fname);
        if (file.exists())
            file.delete();

        try {
            FileOutputStream out = new FileOutputStream(file);
            DrawBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
            out.flush();
            out.close();
            Toast.makeText(this, "File Saved ::" + fname,
                    Toast.LENGTH_SHORT).show();

            sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
                    Uri.parse("file://"
                            + Environment.getExternalStorageDirectory())));

        } catch (Exception e) {
            Toast.makeText(this, "ERROR" + e.toString(), Toast.LENGTH_SHORT)
                    .show();
        }
    }

    return super.onOptionsItemSelected(item);
}

【问题讨论】:

    标签: android canvas android-canvas


    【解决方案1】:

    我已经通过使用这段代码解决了这个问题。 当你保存这个时,只需在画布上用你想要的背景绘制位图。

    public class DrawingView extends View {
    
    
    public Paint mPaint;
    public int width;
    public int height;
    private Bitmap mBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint mBitmapPaint;
    static Context context;
    private Paint circlePaint;
    public boolean eraseMode = false;
    private Path circlePath;
    
    public DrawingView(Context c) {
        super(c);
        context = c;
        initialize();
    }
    
    public void initialize(){
        mPath = new Path();
        mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        circlePaint = new Paint();
        circlePath = new Path();
        circlePaint.setAntiAlias(true);
        circlePaint.setColor(Color.TRANSPARENT);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeJoin(Paint.Join.MITER);
        circlePaint.setStrokeWidth(4f);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.BLACK);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(6);
    }
    
    @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(circlePath, circlePaint);
        super.onDraw(canvas);
    }
    
    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;
    
            circlePath.reset();
            circlePath.addCircle(mX, mY, 30, Path.Direction.CW);
            mCanvas.drawPath(mPath, mPaint);
        }
    }
    
    private void touch_up() {
        mPath.lineTo(mX, mY);
        circlePath.reset();
        mCanvas.drawPath(mPath, mPaint);
        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 void setErase() {
        mPaint.setXfermode(null);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        eraseMode = true;
    }
    
    public void removeErase() {
        mPaint.setXfermode(null);
         eraseMode = false;
    }
    
    public void SaveImage() {
        Bitmap image1 = Bitmap.createScaledBitmap(mBitmap, 1080, 780, true);
    
        File filepath = Environment.getExternalStorageDirectory();
        File file = new File(filepath.getAbsolutePath() + "/NumberAndAlphabet");
        if (!file.exists()) {
            file.mkdir();
        }
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss",
                Locale.getDefault());
        String time = formatter.format(date);
        File dir = new File(file, "Image" + time + ".PNG");
        OutputStream output = null;
        try {
            output = new FileOutputStream(dir);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Bitmap newbitmap = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), image1.getConfig());
        Canvas can = new Canvas(newbitmap);
        can.drawColor(Color.WHITE);
        can.drawBitmap(image1, 0, 0, null);
        newbitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
        Toast.makeText(context, "Image Saved...", Toast.LENGTH_SHORT).show();
    }
    

    }

    【讨论】:

    • 触摸应用程序每次都会崩溃。
    • 你能发布你的 logcat 吗?
    • logcat 显示 circlePath.reset() 的问题; touch_up() 内部
    • 你能完全发布 logcat,因为没有看到 logcat 我无法说出解决方案
    • 你在activity中创建了Paint方法mPaint的对象吗?
    猜你喜欢
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-16
    • 1970-01-01
    相关资源
    最近更新 更多