I want to paint graphics onto a Canvas such that the colors are additive. For example, I want to produce this:
You are on the right track. There are 3 major issues in your code:
Here is what I've got by using xfer mode. What I'm doing - is drawing everything into temporary bitmap and then rendering entire bitmap to main canvas.
You ask why do you need temp bitmap? Good question! If you are drawing everything on a main canvas, your colors will be blended with main canvas background color, so all colors will get messed up. Transparent temp bitmap helps to keep your colors away of other parts of UI
Please make sure you are not allocating anything in onDraw()
- you will run out memory very soon in this way.. Also make sure you have recycled your temp bitmap when you no longer need it.
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));
}
}