我想创建一个画笔,用于在带有处理的PGraphics元素上进行绘图。我希望过去的笔触是可见的。但是,由于每个帧都加载了PGraphics元素,以前的笔画就会立即消失。
然后,我的想法是在setup()中创建PGraphics pg,在void()中复制它,修改原始图形pg,并在每个帧上更新副本。这会产生一个NullPointerException,很可能是因为pg是在安装程序()中本地定义的。
到目前为止,这就是我所得到的:
PGraphics pg;PFont字体;
void setup (){
font = createFont("Pano Bold Kopie.otf", 600);
size(800, 800, P2D);
pg = createGraphics(800, 800, P2D);
pg.beginDraw();
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 () {
copy(pg, 0, 0, width, height, 0, 0, width, height);
loop();
int c;
loadPixels();
for (int x=0; x<width; x++) {
for (int y=0; y<height; y++) {
pg.pixels[mouseX+mouseY*width]=0;
}
}
updatePixels();
}我的最后一个想法(我还没有尝试实现)是将鼠标触摸过的像素添加到列表中,并从这个列表中提取每个帧。但这对我来说似乎相当复杂,因为它可能会导致超长数组,需要在原始图像的基础上进行处理。所以,我希望还有另外一条路可走!
编辑:我的目标是创建一个污迹刷,因此,一种画笔,复制区域从图像的一部分到其他部分。
发布于 2019-09-30 11:33:17
没有必要手动复制像这样的像素。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();
}正如评论所提到的,一种想法是按下样品颜色,然后使用样本颜色,并将其作为拖离源区域的拖曳物。这只显示了读取一个像素。您可能需要尝试采样/读取更多的像素(例如矩形或椭圆)。

此外,上面的代码没有被优化。一些事情可以加快一些,如读取像素,提取颜色,计算距离等。
例如:
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();
}这样做的目的是简单地从清晰、可读的代码开始,并且只在最后才开始,如果需要的话,查看优化。
https://stackoverflow.com/questions/58166590
复制相似问题