我正在尝试找到一种方法,可以从自定义颜色选择器中选择颜色并将其设置为画布的背景,而不会删除任何现有的绘制内容。我正在创建一个应用程序,可以在画布上进行绘制,然后将其保存为PNG格式。但是,当我将新的背景设置为当前画布时,所有的绘图都消失了。我使用的代码类似于:
mCanvas.drawColor(picker.getColor());
有什么想法可以让事情正常工作吗?
我正在尝试找到一种方法,可以从自定义颜色选择器中选择颜色并将其设置为画布的背景,而不会删除任何现有的绘制内容。我正在创建一个应用程序,可以在画布上进行绘制,然后将其保存为PNG格式。但是,当我将新的背景设置为当前画布时,所有的绘图都消失了。我使用的代码类似于:
mCanvas.drawColor(picker.getColor());
有什么想法可以让事情正常工作吗?
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
类的测试Activity。这两个文件在Android项目中都是自包含的,因此您可以在真实设备上轻松测试它,无需麻烦。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);
}
}
如果您想在画布中进行更改,则必须调用invalidate以应用这些更改到屏幕上。如果您调用invalidate,那么您的onDraw()
方法将被调用。
如果您只想从颜色选择器更改画布的背景颜色,则保存颜色值到变量中,并在保存变量后立即调用invalidate。现在您的onDraw()
将被调用。现在通过在onDraw()
中调用setBackgroundColor(color variable)
来更改画布的背景,并绘制其他所有内容。
canvas.drawARGB(200, 0, 0, 0);
使视图变暗。 - oxied@ Android-Droid
这两行代码对我非常有效。每当用户点击任何颜色(例如:红色),将该颜色设置为mPaint,如下:
mPaint.setColor(Color.RED);
每当您想更改画布颜色时
dv.setBackgroundColor(mPaint.getColor());
其中dv是扩展视图(自定义视图)的类的对象。 试一下,如果遇到任何问题,请告诉我。
for (x...)
for (y...)
if (bitmap.getPixel(x,y) == oldBackgroundColor)
bitmap.setPixel(x,y,newBackgroundColor)
或者,您可以在离屏位图上绘制内容,先绘制背景,然后再将离屏绘制到实际位图上。这样,您就可以更改下一次两步绘制时使用的背景颜色。
@Override
public Bitmap transform(final Bitmap source) {
//Background for transparent images
Bitmap backg = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
backg.eraseColor(Color.WHITE); // Any color you want...
Paint back = new Paint();
BitmapShader backshader = new BitmapShader(backg,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
back.setShader(backshader);
back.setAntiAlias(true);
// Image for the draw
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP,
Shader.TileMode.CLAMP));
Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
Canvas canvas = new Canvas(output);
// IMPORTANT THING
canvas.drawRoundRect(new RectF(margin, margin, source.getWidth()
- margin, source.getHeight() - margin), radius, radius, back); // Draw the background first...
canvas.drawRoundRect(new RectF(margin, margin, source.getWidth()
- margin, source.getHeight() - margin), radius, radius, paint); // And then Draw the image, so it draws on top of the background
if (source != output) {
source.recycle();
}
// This is for if i want to put a border in the drawable, its optional
Paint paint1 = new Paint();
paint1.setColor(Color.parseColor("#CC6C7B8B"));
paint1.setStyle(Style.STROKE);
paint1.setAntiAlias(true);
paint1.setStrokeWidth(2);
canvas.drawRoundRect(new RectF(margin, margin, source.getWidth()
- margin, source.getHeight() - margin), radius, radius, paint1);
// and then, return the final drawable...
return output;
}
希望能有所帮助...