不从它丢失任何图纸的Andr​​oid变化画布背景颜色 [英] Android change canvas background color without losing any drawings from it

查看:120
本文介绍了不从它丢失任何图纸的Andr​​oid变化画布背景颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到一种方法来设置画布的背景颜色接走自定义颜色选择器不就可以删除任何图纸。我试图创建一个可以借鉴的画布,比其保存为PNG的应用程序。但是,当我设置一个新的背景到当前画布中,所有的图纸都没有了。我使用的是这样的:

I'm trying to find a way to set background of canvas with a color picked up from custom color picker without removing any drawings on it. I'm trying to create an application which can draw on canvas and than save it as png. But when I set a new background to the current canvas, all drawings are gone. I'm using something like this :

mCanvas.drawColor(picker.getColor());

任何想法我怎么能得到的东西的工作?

Any ideas how I can get things to work?

推荐答案

已经给你的问题​​的答案都指向正确的方向:你需要单独背景颜色块,并在不同层次的前景图,然后节约整体在一个.png文件之前,将它们合并。这就是Adobe公司的Photoshop的工作流程设计,以及...这有一定道理,如果我们仔细想想:举个例子像MSPAINT软件:因为它不使用层,它必须依赖于这样的东西此时,floodFill算法完成(尽管在一个不完整的方式)的东西远程类似背景的变化...

The answers already given to your question are all pointing in the right direction: you do need to separate your background color block and your foreground drawing in separate layers, then merge them before saving the whole of it in a .png file. This is how Adobe Photoshop workflow is designed as well... It does make sense, if we think about it: take for example a software like MsPaint: because it doesn't use layers, it has to rely on stuff like floodfill algorithms to accomplish (albeit in an incomplete way) something remotely similar to a background change...

要实现这样的事情的一种方法是实例化由2个不同的位图支持2画布对象。第一画布-位图对将用于绘图的前景,而第二画布-位图对将用于您的合并层图形(即前景绘图+背景色块)。然后第二位图是什么将被保存到一个PNG文件,当你需要它来保存。这样,我们的第一帆布-位图对存储你的前景信息,如果背景颜色变化需要进行哪些不被破坏。每次操作制成,这些层可以合并到第二画布-位图对,使得总是有具有正确的内容,是准备要保存在你随心所欲一个位图。

One way to implement such a thing would be to instantiate 2 Canvas objects backed by 2 different bitmaps. The first Canvas-Bitmap pair would be used for your drawing at the foreground, and the second Canvas-Bitmap pair would be used for your merged-layers drawing (i.e. foreground drawing + background color block). Then the 2nd Bitmap is what will be saved to a .png file when you need it to be saved. This way, our first Canvas-Bitmap pair stores your foreground info, which is not destroyed if a background color change needs to be made. Everytime an operation is made, the layers can be merged into the 2nd Canvas-Bitmap pair so that there is always a Bitmap with the correct content that is ready to be saved at your whim.

下面是一个自定义视图我作出安排,以清除这种方法了。它实现了用于油漆用手指在触摸屏上的蓝线的简单观点,与背景颜色的变化取决于XY位置说的手指,从而表现出背景颜色更改,恕不固有不必要的code的复杂性完全实现了色轮/菜单/ 尤其的:

Here is a custom View I made so as to clear this methodology up. It implements a simple view used to paint a blue line on the touch-screen using a finger, with a background color changing depending on the X-Y position of said finger so as to demonstrate a background color change without unnecessary code complexity inherent of a complete implementation with a color wheel/menus/inter alia:

package com.epichorns.basicpaint;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.Paint.Style;
import android.view.View;

public class PaintView extends View{

    Bitmap mMergedLayersBitmap=null; //Note: this bitmap here contains the whole of the drawing (background+foreground) to be saved.
    Canvas mMergedLayersCanvas=null;

    Bitmap mBitmap = null; //bitmap onto which we draw our stuff
    Canvas mCanvas = null; //Main canvas. Will be linked to a .bmp file
    int mBackgroundColor = 0xFF000000; //default background color
    Paint mDefaultPaint = new Paint();

    Paint mDrawPaint = new Paint(); //used for painting example foreground stuff... We draw line segments.
    Point mDrawCoor = new Point(); //used to store last location on our PaintView that was finger-touched

    //Constructor: we instantiate 2 Canvas-Bitmap pairs
    public PaintView(Context context, int width, int height) {
        super(context);
        mMergedLayersBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
        mMergedLayersCanvas = new Canvas(mMergedLayersBitmap);

        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
    }

    //Change background color
    public void changeColor(int newColor){
        mBackgroundColor = newColor;
        invalidate(); //refresh view: this will indirectly invoke onDraw soon afterwards
    }

    //Called by user of PaintView in order to start a painting "stroke" (finger touching touch-screen): stores the 
    //location of the finger when it first touched the screen
    public void startDraw(int x, int y, int radius, int color){
        mDrawPaint.setColor(color);
        mDrawPaint.setStyle(Style.STROKE);
        mDrawPaint.setStrokeWidth(radius);
        mDrawCoor.x = x;
        mDrawCoor.y = y;        
    }

    //Called by user of PaintView when finger touching touch-screen is moving (must be called after a startDraw, 
    //as the latter initializes a couple of necessary things)
    public void continueDraw(int x, int y){
        mCanvas.drawLine(mDrawCoor.x, mDrawCoor.y, x, y, mDrawPaint);
        mDrawCoor.x = x;
        mDrawCoor.y = y;
        invalidate(); //refresh view: this will indirectly invoke onDraw soon afterwards
    }

    //Merge the foreground Canvas-Bitmap with a solid background color, then stores this in the 2nd Canvas-Bitmap pair.
    private void mergeLayers(){
        mMergedLayersCanvas.drawColor(mBackgroundColor);
        mMergedLayersCanvas.drawBitmap(mBitmap, 0, 0, mDefaultPaint);
    }

    @Override
    public void onDraw(Canvas canvas){
        mergeLayers();
        canvas.drawBitmap(mMergedLayersBitmap, 0, 0, mDefaultPaint);
    }

}

为了测试这个观点,在这里是使用 PaintView 类测试活动。这两个文件都是自给自足的Andr​​oid项目,让您可以在真正的设备上测试它毫不费力:

In order to test this view, here is a test Activity that uses the PaintView class. Both of those files are self-sufficient in an Android project, so that you can test it on your real device without hassle:

package com.epichorns.basicpaint;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;


import com.epichorns.basicpaint.PaintView;
public class BasicPaintActivity extends Activity {
    PaintView mPaintView=null;
    LinearLayout mL = null;
    boolean mIsDrawing=false;
    int mBackgroundColor = 0xFF000000;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Display display = getWindowManager().getDefaultDisplay();       
        final float dispWidth = (float)display.getWidth();
        final float dispHeight = (float)display.getHeight();

        mPaintView = new PaintView(this, display.getWidth(), display.getHeight());    
        mPaintView.changeColor(mBackgroundColor);
        mPaintView.setOnTouchListener(new View.OnTouchListener(){

            public boolean onTouch(View v, MotionEvent event) {

            if(event.getAction()==MotionEvent.ACTION_DOWN){
                    mPaintView.startDraw((int)event.getX(), (int)event.getY(), 6, 0x806060FF);              
                    mIsDrawing=true;
                    return true;
                }
                else if(event.getAction()==MotionEvent.ACTION_UP){
                    mIsDrawing=false;
                    return true;
                }
                else if(event.getAction()==MotionEvent.ACTION_MOVE){
                    if(mIsDrawing){

                        //To demonstrate background change, change background color depending on X-Y position
                        int r = (int)(255f*event.getX()/dispWidth);
                        int g = (int)(255f*event.getY()/dispHeight);
                        mBackgroundColor = Color.argb(0xFF, r,g, 0x00);
                        Log.d("DEBUG1", "Color channels: (r, g) = ("+String.valueOf(r)+", "+String.valueOf(g)+")");
                        mPaintView.changeColor(mBackgroundColor);

                        //now, draw stuff where finger was dragging...
                        mPaintView.continueDraw((int)event.getX(), (int)event.getY());
                        return true;
                    }
                    else{
                        return false;
                    }

                }

                return false;
            }

        });

        setContentView(mPaintView);
    }




}

这篇关于不从它丢失任何图纸的Andr​​oid变化画布背景颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆