我想在Canvas上绘制图形,使颜色成为可加。例如,我想要产生这个:
但相反,我得到了这个:
请注意,半白,半黑背景是有意的,只是为了看看alpha如何与两个背景相互作用。我很乐意在任何一个背景下工作。这是我的代码:
public class VennColorsActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
class VennView extends View {
public VennView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int alpha = 60, val = 255;
int ar = Color.argb(alpha, val, 0, 0);
int ag = Color.argb(alpha, 0, val, 0);
int ab = Color.argb(alpha, 0, 0, val);
float w = canvas.getWidth();
float h = canvas.getHeight();
float cx = w / 2f;
float cy = h / 2;
float r = w / 5;
float tx = (float) (r * Math.cos(30 * Math.PI / 180));
float ty = (float) (r * Math.sin(30 * Math.PI / 180));
float expand = 1.5f;
Paint paint = new Paint();
paint.setColor(Color.WHITE);
canvas.drawRect(new Rect(0, 0, (int) w, (int) (h / 2)), paint);
PorterDuff.Mode mode = android.graphics.PorterDuff.Mode.ADD;
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColorFilter(new PorterDuffColorFilter(ar, mode));
paint.setColor(ar);
canvas.drawCircle(cx, cy - r, expand * r, paint);
paint.setColorFilter(new PorterDuffColorFilter(ag, mode));
paint.setColor(ag);
canvas.drawCircle(cx - tx, cy + ty, expand * r, paint);
paint.setColorFilter(new PorterDuffColorFilter(ab, mode));
paint.setColor(ab);
canvas.drawCircle(cx + tx, cy + ty, expand * r, paint);
}
}
this.setContentView(new VennView(this));
}
}
有人可以帮我理解如何在Android图形中使用添加颜色进行绘画吗?
答案 0 :(得分:27)
你走在正确的轨道上。您的代码中存在3个主要问题:
这是我使用xfer模式得到的。我正在做的是 - 将所有内容绘制到临时位图中,然后将整个位图渲染到主画布。
你问为什么需要临时位图?好问题!如果您在主画布上绘制所有内容,您的颜色将与主画布背景颜色混合,因此所有颜色都会混乱。透明的临时位图有助于使您的颜色远离UI的其他部分
请确保您没有在onDraw()
中分配任何内容 - 您将很快以这种方式耗尽内存。还要确保在不再需要时回收了临时位图。
package com.example.stack2;
import android.app.Activity;
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.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.View;
public class YouAreWelcome extends Activity {
Bitmap tempBmp = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
Canvas c = new Canvas();
Paint paint = new Paint();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
class VennView extends View {
public VennView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(tempBmp.isRecycled() || tempBmp.getWidth()!=canvas.getWidth() || tempBmp.getHeight()!=canvas.getHeight())
{
tempBmp.recycle();
tempBmp = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888);
c.setBitmap(tempBmp);
}
//clear previous drawings
c.drawColor(Color.TRANSPARENT, Mode.CLEAR);
int alpha = 255, val = 255;
int ar = Color.argb(alpha, val, 0, 0);
int ag = Color.argb(alpha, 0, val, 0);
int ab = Color.argb(alpha, 0, 0, val);
float w = canvas.getWidth();
float h = canvas.getHeight();
float cx = w / 2f;
float cy = h / 2;
float r = w / 5;
float tx = (float) (r * Math.cos(30 * Math.PI / 180));
float ty = (float) (r * Math.sin(30 * Math.PI / 180));
float expand = 1.5f;
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(Mode.ADD));
paint.setColor(ar);
c.drawCircle(cx, cy - r, expand * r, paint);
paint.setColor(ag);
c.drawCircle(cx - tx, cy + ty, expand * r, paint);
paint.setColor(ab);
c.drawCircle(cx + tx, cy + ty, expand * r, paint);
canvas.drawBitmap(tempBmp, 0, 0, null);
}
}
this.setContentView(new VennView(this));
}
}
答案 1 :(得分:2)
再次感谢帕维尔。这对我来说很难自己解决。我正在回答我自己的问题,以便更好地深入细节,但我已经接受了你的最佳答案。
你是对的,我不想创建和管理屏幕外的Bitmap(和Canvas)。这就是为什么我提到黑色或白色背景可以使这项工作正常的原因。
在我看到有效的工作之前,我从不关心性能,但在此之后我会分享你的谨慎态度。编辑您的版本以解决该问题并删除这些成员会给出以下实现。
这很强大吗?注意两个对Canvas.drawColor()的调用,我怀疑它也可以组合成一个。
package com.superliminal.android.test.venn;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.view.View;
public class VennColorsActivity extends Activity {
private Paint paint = new Paint();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
class VennView extends View {
public VennView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.BLACK);
canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
int alpha = 255, val = 255;
int ar = Color.argb(alpha, val, 0, 0);
int ag = Color.argb(alpha, 0, val, 0);
int ab = Color.argb(alpha, 0, 0, val);
float w = canvas.getWidth();
float h = canvas.getHeight();
float cx = w / 2f;
float cy = h / 2;
float r = w / 5;
float tx = (float) (r * Math.cos(30 * Math.PI / 180));
float ty = (float) (r * Math.sin(30 * Math.PI / 180));
float expand = 1.5f;
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(Mode.ADD));
paint.setColor(ar);
canvas.drawCircle(cx, cy - r, expand * r, paint);
paint.setColor(ag);
canvas.drawCircle(cx - tx, cy + ty, expand * r, paint);
paint.setColor(ab);
canvas.drawCircle(cx + tx, cy + ty, expand * r, paint);
}
}
setContentView(new VennView(this));
}
}