I am trying to create a round brush with blurred edges in Processing through the following code. The circle shape is drawn pixel by pixel because in the actual version, I try to draw with pixels taken from the PGraphic pg.
PFont font;
PGraphics pg;
int X;
int Y;
int rad = 20;
void setup (){
size(800, 800, P2D);
background(0);
noStroke();
pg = createGraphics(800, 800, JAVA2D);
pg.beginDraw();
pg.fill(255);
pg.noStroke();
pg.textFont(font);
pg.textSize(400);
pg.pushMatrix();
pg.translate(width/2, height/2-140);
pg.textAlign(CENTER, CENTER);
pg.text("b", 0 , 0);
pg.popMatrix();
pg.endDraw();
}
void draw () {
image(pg,0,0);
}
void mousePressed(){
X = mouseX;
Y = mouseY;
}
void mouseDragged(){
for (int x=0; x<rad; x++) {
for (int y=0; y<rad; y++) {
float distance = sqrt(pow(x,2)+pow(y,2));
float alpha = 255-map(distance,0,rad,0,255);
if (sqrt(pow(x,2)+pow(y,2)) < rad){
pg.beginDraw();
pg.set(mouseX+x,mouseY+y,color(255,255,255, alpha));
pg.set(mouseX-x,mouseY+y,color(255,255,255, alpha));
pg.set(mouseX+x,mouseY-y,color(255,255,255, alpha));
pg.set(mouseX-x,mouseY-y,color(255,255,255, alpha));
pg.endDraw();
}
}
}
}

Create a function which draw a single dot to a PGraphics object:
void DrawPen(PGraphics pg, int cptX, int cptY, int r) {
pg.beginDraw();
for (int x = 0; x < r; ++x) {
for (int y = 0; y < r; ++y) {
float distance = sqrt(x*x + y*y);
float alpha = 255-map(distance,0,r,0,255);
if (distance < r) {
pg.set(cptX+x,cptY+y,color(255,255,255, alpha));
pg.set(cptX-x,cptY+y,color(255,255,255, alpha));
pg.set(cptX+x,cptY-y,color(255,255,255, alpha));
pg.set(cptX-x,cptY-y,color(255,255,255, alpha));
}
}
}
pg.endDraw();
}
Draw a dot to a separate PGraphics object in setup
PGraphics pg;
PGraphics pg_pen;
int rad = 20;
void setup (){
size(800, 800, P2D);
pg = createGraphics(800, 800, JAVA2D);
pg.beginDraw();
// [...]
pg.endDraw();
pg_pen = createGraphics(2*rad, 2*rad, JAVA2D);
DrawPen(pg_pen, rad, rad, rad);
}
When the mouse is dragged then blend the pg_pen to the common PGraphics object (pg) at the current mouse position:
void mouseDragged(){
pg.beginDraw();
pg.image(pg_pen, mouseX-rad, mouseY-rad);
pg.endDraw();
}
For the seek of completeness the draw function:
void draw () {
background(0);
image(pg,0,0);
}

[...] and tried to get the color from the white part to draw on the black part.
Add a color parameter to the DrawPen function and clear the pen PGraphics before drawing to it:
void DrawPen(PGraphics pg, int cptX, int cptY, int r, color c) {
pg.beginDraw();
pg.clear();
for (int x = 0; x < r; ++x) {
for (int y = 0; y < r; ++y) {
float distance = sqrt(x*x + y*y);
float alpha = 255-map(distance,0,r,0,255);
if (distance < r) {
color pc = color(red(c),green(c),blue(c), alpha);
pg.set(cptX+x,cptY+y,pc);
pg.set(cptX-x,cptY+y,pc);
pg.set(cptX+x,cptY-y,pc);
pg.set(cptX-x,cptY-y,pc);
}
}
}
pg.endDraw();
}
Get the color in the mouse pressed event call back and change the color of the pen:
void mousePressed() {
color c = pg.get(mouseX, mouseY);
println(c);
DrawPen(pg_pen, rad, rad, rad, c);
}

Note, the color is get from the pg object and not from the screen. If you want to get the color from the screen then it has to be (without .pg):
color c = get(mouseX, mouseY);
Further the color is changed any time when any mouse is pressed (pressed not dragged). Possibly you want to change the color when the right mouse button is pressed and paint when the left mouse button is pressed:
void mousePressed() {
if (mouseButton == RIGHT) {
color c = pg.get(mouseX, mouseY);
println(c);
DrawPen(pg_pen, rad, rad, rad, c);
}
}
add a "background(0);" before "image(pg,0,0);" in your drawing method, that way you reset the background every time, if you don't do that the program will keep drawing every frame images on top of each other's, which will make the low opacity pixel gain opacity slowly every frame until reaching 100%
void draw () {
background(0);
image(pg,0,0);
}
Edit: After testing your code I noticed there was a problem with the way you were creating those circles, making it super slow to run (every frame you go through that double for loop to draw one circle ) and also gave that weird black edges problem, so here is what I did:
First I used your variable pg and drew one circle on it on the startup, Then I declared another PGraphics 'pg_all', where I drew one pg every call of the mousedrag method, I tested it on multiple backgrounds it seems like working fine, here is the final code, let me know if you didn't understand a part or want to do it differently:
PFont font;
PGraphics pg;
PGraphics pg_all;
int X;
int Y;
int rad = 20;
void setup (){
size(800, 800, P2D);
background(0);
noStroke();
pg_all = createGraphics(800, 800, JAVA2D);
pg_all.beginDraw();
pg_all.endDraw();
pg = createGraphics(800, 800, JAVA2D);
pg.beginDraw();
for (int x=0; x<rad; x++) {
for (int y=0; y<rad; y++) {
float distance = sqrt(pow(x,2)+pow(y,2));
float alpha = 255-map(distance,0,rad,0,255);
if (sqrt(pow(x,2)+pow(y,2)) < rad){
pg.beginDraw();
pg.set(20+x,20+y,color(255,255,255, alpha));
pg.set(20-x,20+y,color(255,255,255, alpha));
pg.set(20+x,20-y,color(255,255,255, alpha));
pg.set(20-x,20-y,color(255,255,255, alpha));
pg.endDraw();
}
}
}
pg.endDraw();
}
void draw () {
background(0);
image(pg_all,0,0);
}
void mouseDragged(){
X = mouseX;
Y = mouseY;
pg_all.beginDraw();
pg_all.image(pg,X-rad,Y-rad);
pg_all.endDraw();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With