Нет необходимости вручную копировать подобные пиксели. Класс PGraphics расширяет PImage
, что означает, что вы можете просто визуализировать его, например, с помощью image(pg,0,0);
.
Еще одна вещь, которую вы можете сделать, это старый трюк для исчезновения фона: вместо этогополностью очистив пиксели, вы можете визуализировать эскиз размером с немного непрозрачный прямоугольник без обводки.
Вот краткое доказательство концепции на основе вашего кода:
PFont font;
PGraphics pg;
void setup (){
//font = createFont("Pano Bold Kopie.otf", 600);
font = createFont("Verdana",600);
size(800, 800, P2D);
// clear main background once
background(0);
// prep fading background
noStroke();
// black fill with 10/255 transparnecy
fill(0,10);
pg = createGraphics(800, 800, P2D);
pg.beginDraw();
// leave the PGraphics instance transparent
//pg.background(0);
pg.fill(255);
pg.textFont(font);
pg.textSize(400);
pg.pushMatrix();
pg.translate(width/2, height/2-140);
pg.textAlign(CENTER, CENTER);
pg.text("a", 0 , 0);
pg.popMatrix();
pg.endDraw();
}
void draw () {
// test with mouse pressed
if(mousePressed){
// slowly fade/clear the background by drawing a slightly opaque rectangle
rect(0,0,width,height);
}
// don't clear the background, render the PGraphics layer directly
image(pg, mouseX - pg.width / 2, mouseY - pg.height / 2);
}
Если вы удерживаете мышь нажатой, выможно увидеть эффект затухания. (изменение прозрачности на 10 до более высокого значения с ускорением затухания)
Обновление Чтобы создать размытую кисть, вы все равно можете пробовать пиксели и затем до некоторой степени манипулировать считанными цветами. Есть много способов реализовать эффект пятна, основанный на том, чего вы хотите добиться визуально.
Вот очень грубое подтверждение концепции:
PFont font;
PGraphics pg;
int pressX;
int pressY;
void setup (){
//font = createFont("Pano Bold Kopie.otf", 600);
font = createFont("Verdana",600);
size(800, 800, P2D);
// clear main background once
background(0);
// prep fading background
noStroke();
// black fill with 10/255 transparnecy
fill(0,10);
pg = createGraphics(800, 800, JAVA2D);
pg.beginDraw();
// leave the PGraphics instance transparent
//pg.background(0);
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("a", 0 , 0);
pg.popMatrix();
pg.endDraw();
}
void draw () {
image(pg,0,0);
}
void mousePressed(){
pressX = mouseX;
pressY = mouseY;
}
void mouseDragged(){
// sample the colour where mouse was pressed
color sample = pg.get(pressX,pressY);
// calculate the distance from where the "smudge" started to where it is
float distance = dist(pressX,pressY,mouseX,mouseY);
// map this distance to transparency so the further the distance the less smudge (e.g. short distance, high alpha, large distnace, small alpha)
float alpha = map(distance,0,30,255,0);
// map distance to "brush size"
float size = map(distance,0,30,30,0);
// extract r,g,b values
float r = red(sample);
float g = green(sample);
float b = blue(sample);
// set new r,g,b,a values
pg.beginDraw();
pg.fill(r,g,b,alpha);
pg.ellipse(mouseX,mouseY,size,size);
pg.endDraw();
}
Как отмечается в комментариях, одна идея состоит в том, чтобыобразец цвета на прессе, затем используйте образец цвета и затемните его, перетаскивая из области источника. Это показывает просто чтение одного пикселя. Возможно, вы захотите поэкспериментировать с выборкой / считыванием большего количества пикселей (например, прямоугольника или эллипса).
![smudge a demo](https://i.stack.imgur.com/FCS1A.jpg)
Кроме того, приведенный выше код не оптимизирован. Несколько вещей могут быть немного ускорены, такие как считывание пикселей, выделение цветов, вычисление расстояния и т. Д.
Например:
void mouseDragged(){
// sample the colour where mouse was pressed
color sample = pg.pixels[pressX + (pressY * pg.width)];
// calculate the distance from where the "smudge" started to where it is (can use manual distance squared if this is too slow)
float distance = dist(pressX,pressY,mouseX,mouseY);
// map this distance to transparency so the further the distance the less smudge (e.g. short distance, high alpha, large distnace, small alpha)
float alpha = map(distance,0,30,255,0);
// map distance to "brush size"
float size = map(distance,0,30,30,0);
// extract r,g,b values
int r = (sample >> 16) & 0xFF; // Like red(), but faster
int g = (sample >> 8) & 0xFF;
int b = sample & 0xFF;
// set new r,g,b,a values
pg.beginDraw();
pg.fill(r,g,b,alpha);
pg.ellipse(mouseX,mouseY,size,size);
pg.endDraw();
}
Идея состоит в том, чтобы начать с простого с четкого, читаемогокод и только в конце, при необходимости посмотрите на оптимизацию.