我正在寻求有关编程语言/环境处理的帮助。
我对Processing非常陌生,我正在尝试使用openprocessing.org上的某个代码。我非常喜欢这段代码提供的视觉效果,我想进一步使用它。不幸的是,输出分辨率非常低。因此,我正在寻找能够帮助我弄清楚如何a)增加所生成形状的大小或分辨率的人,以及b)将所有内容保存为pdf文件。
您可以在此处找到原始代码:https://www.openprocessing.org/sketch/377730
这是代码:
import java.util.Arrays;
float[][] z, v, a;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
size(512, 512);
colorMode(RGB, 2);
z = new float[width][height];
v = new float[width][height];
a = new float[width][height];
loadPixels();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw() {
for (int x = 1; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1])/4 - v[x][y];
}
}
for (int x = 1; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
v[x][y] += a[x][y];
z[x][y] += v[x][y];
pixels[width*y+x] = color(sin(z[x][y]) + 1, cos(z[x][y]), 1);
}
}
updatePixels();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void move() {
if (mouseX > -1 && mouseX < width && mouseY > -1 && mouseY < height) {
v[mouseX][mouseY] = randomGaussian() * TAU;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseClicked() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseDragged() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keyPressed() {
noLoop();
for (int x = 0; x < width; x++) Arrays.fill(z[x], 0);
for (int x = 0; x < width; x++) Arrays.fill(v[x], 0);
loop();
}
到目前为止,我已经尝试了一个假设的高分辨率方法发布到Processing-Forum,但这对我来说并不起作用,至少在上面代码的上下文中我没有使用过。 。这是论坛中的一段代码,演示了一种用户以高分辨率保存处理输出输出的方法:
int dim = 5000;
int dimScreen = dim/10;
color c1 = #AFA786;
color c2 = #000000;
void setup() { size(dimScreen,dimScreen); }
void draw() { exampleSketch(); }
void exampleSketch() {
for (int y=0; y<=height; y++) {
stroke(lerpColor(c1,c2,float(y)/height));
line(0,y,width,y);
}
stroke(#FFFFFF);
fill(#BBBBBB);
ellipse(width/2, height/2, width/2, height/2);
line(0, 0, width, height);
}
void keyPressed() {
if (key ==' ') {
g = createGraphics(dim,dim,JAVA2D);
this.height = dim;
this.width = dim;
g.beginDraw();
exampleSketch();
g.endDraw();
save("result.png");
println("screenshot saved");
this.height = dimScreen;
this.width = dimScreen;
}
}
我非常感谢那些熟练使用Processing和Java帮助我的人。非常感谢,祝大家晚安。
这是我尝试将第二个代码实现到第一个代码中:
import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;
int dim = 900;
int dimScreen = dim/10;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
size(900, 900);
smooth(8);
colorMode(RGB, 2);
z = new float[width][height];
v = new float[width][height];
a = new float[width][height];
loadPixels();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw() { exampleSketch(); }
void exampleSketch() {
for (int x = 1; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1])/4 - v[x][y];
}
}
for (int x = 1; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
v[x][y] += a[x][y];
z[x][y] += v[x][y];
pixels[width*y+x] = color(sin(z[x][y]) + 1, cos(z[x][y]), 1);
}
}
updatePixels();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void move() {
if (mouseX > -1 && mouseX < width && mouseY > -1 && mouseY < height) {
v[mouseX][mouseY] = randomGaussian() * TAU;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseClicked() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseDragged() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void keyPressed() {
if (key ==' ') {
g = createGraphics(dim,dim,JAVA2D);
this.height = dim;
this.width = dim;
g.beginDraw();
exampleSketch();
g.endDraw();
save("result2.png");
println("screenshot saved");
this.height = 900;
this.width = 900;
}
}
编辑:两张屏幕截图,比较了实施乔治白色背景解决方案之前和之后的不同视觉效果:
答案 0 :(得分:2)
除了Kevin的答案之外,您还可以使用JVisualVM查看花费大部分CPU时间的位置。在不同时间对CPU进行采样和分析后,大部分时间都是计算RGB值:
最好从优化时占用大部分CPU的功能开始。
这是草图的一个版本,它使用默认的0-255 RGB范围并计算内联的RGB值(将A,R,G,B字节放在一起):
import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;
int dim = 900;
int dimScreen = dim/10;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
size(900, 900);
smooth(8);
//colorMode(RGB, 2);
z = new float[width][height];
v = new float[width][height];
a = new float[width][height];
loadPixels();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw() { exampleSketch(); }
void exampleSketch() {
int r,g,b = 255;
for (int x = 1; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
//}
//}
// //for (int x = 1; x < width-1; x++) {
//for (int y = 1; y < height-1; y++) {
v[x][y] += a[x][y];
z[x][y] += v[x][y];
r = ((int)((sin(z[x][y]) + 1) * 128) << 16);
g = ((int)((cos(z[x][y]) * 128)) << 8);
pixels[width*y+x] = 0xff000000 | r | g | b;
}
}
updatePixels();
fill(0);
text((int)frameRate+"fps",15,15);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void move() {
if (mouseX > -1 && mouseX < width && mouseY > -1 && mouseY < height) {
v[mouseX][mouseY] = randomGaussian() * TAU;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseClicked() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseDragged() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int screenshotCount=1;
void keyPressed() {
if (key ==' ') {
save("result"+nf(screenshotCount,4)+".png");
println("screenshot saved");
}
}
//http://stackoverflow.com/questions/40350644/high-resolution-processing-output
更新: 这是一个修改过的函数,它映射值使背景为白色:
void exampleSketch() {
float rv,gv;
int r,g,b = 255;
for (int x = 1; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
//compute accumulated value of neighbour cells(left+right+top+bottom), average (/4 or * .25) then subtract the current cell from v
a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
//increment current v cell by the current accumulated cell
v[x][y] += a[x][y];
//increment current z (final/result) cell by the updated v cell
z[x][y] += v[x][y];
//in short z[x][y] += v[x][y] + ((v[-1][0] + v[+1][0] + v[0][-1] + v[0][+1]) / 4 - v[x][y])
//scale sin(z) and cos(z) results to 0-255: sin/cos returns -1.0 to 1.0 then 1.0 is added -> 0.0 to 2.0 , then 128 is multiplied = 0-255
rv = (sin(z[x][y]) + 1.0) * 128;
gv = (cos(z[x][y]) + 1.0) * 128;
//contrain to 0-255
if(rv < 0) rv = 0;
if(rv > 255) rv = 255;
if(gv < 0) gv = 0;
if(gv > 255) gv = 255;
//cast to int and shift
r = ((int)(rv) << 16);
g = ((int)(gv) << 8);
//alpha (0xff000000) cobined with r , g, b
int argb = 0xff000000 | r | g | b;
pixels[width*y+x] = argb;
}
}
updatePixels();
fill(0);
text((int)frameRate+"fps",15,15);
}
以下我可以保存的内容:
更新2 : 这是一个计算透明度值而不是白色的版本:
import processing.pdf.*;
import java.util.Arrays;
float[][] z, v, a;
int dim = 900;
int dimScreen = dim/10;
PImage canvas;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {
size(900, 900);
smooth(8);
//colorMode(RGB, 2);
z = new float[width][height];
v = new float[width][height];
a = new float[width][height];
loadPixels();
canvas = createImage(width,height,ARGB);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void draw() { exampleSketch(); }
void exampleSketch() {
float rs,gc,rv,gv;
int r,g,b = 255;
for (int x = 1; x < width-1; x++) {
for (int y = 1; y < height-1; y++) {
//compute accumulated value of neighbour cells(left+right+top+bottom), average (/4 or * .25) then subtract the current cell from v
a[x][y] = (v[x-1][y] + v[x+1][y] + v[x][y-1] + v[x][y+1]) * .25 - v[x][y];
//increment current v cell by the current accumulated cell
v[x][y] += a[x][y];
//increment current z (final/result) cell by the updated v cell
z[x][y] += v[x][y];
//in short z[x][y] += v[x][y] + ((v[-1][0] + v[+1][0] + v[0][-1] + v[0][+1]) / 4 - v[x][y])
//scale sin(z) and cos(z) results to 0-255
rs = sin(z[x][y]) + 1.0;
gc = cos(z[x][y]) + 1.0;
rv = rs * 128;
gv = gc * 128;
//contrain to 0-255
if(rv < 0) rv = 0;
if(rv > 255) rv = 255;
if(gv < 0) gv = 0;
if(gv > 255) gv = 255;
//cast to int and shift
r = ((int)(rv) << 16);
g = ((int)(gv) << 8);
//average sin/cos results = use the sin/cos results used for red/green channels, scale them by half (128) brightness and add them up
//then subtract that from the max (255) to invert the alpha(transparency) value
int alpha = 255-(int)((rs * 128) + (gc * 128));
int argb = alpha << 24 | r | g | b;
canvas.pixels[width*y+x] = argb;
}
}
canvas.updatePixels();
image(canvas,0,0);
fill(0);
text((int)frameRate+"fps",15,15);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void move() {
if (mouseX > -1 && mouseX < width && mouseY > -1 && mouseY < height) {
v[mouseX][mouseY] = randomGaussian() * TAU;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseClicked() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void mouseDragged() { move(); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int screenshotCount=1;
void keyPressed() {
if (key ==' ') {
canvas.save("result"+nf(screenshotCount,4)+".png");
println("screenshot saved");
}
}
不幸的是,我没有时间深入了解更多细节并提供快速解决方案,但我可以提供一些可能有所帮助的指示:
这看起来像一个简化的BZ or Grey Scott reaction diffusion模拟:
查看Daniel Shiffman's video tutorial on it:它将帮助您更好地理解算法并编写更高效的实现。
还有一些更加强硬的方法可以让人想到:
答案 1 :(得分:1)
你真的在谈论两件不同的事情:
Thing One:让彩色斑点更大。这有点烦人,因为算法使用像素数组,所以它不像调用scale()
函数那么简单。
事实上,因为算法适用于像素,所以任何改变分辨率的简单方法都会变得像素化。
您在论坛上获得的解决方案是绘制到屏幕外缓冲区,这实际上不会改变blob的大小。 更改blob大小的唯一方法是更改算法。
你可能能够修改你操作数组的方式,以便blob更大,但老实说,我并不完全理解数组现在正在做什么,这使得很难提供帮助。
事情二:导出为图片。
最简单的方法是简单地调用save("ImageNameHere.png")
函数。这将创建一个与草图大小相同的图像,其中包含调用该函数时屏幕上显示的内容。
您在论坛上找到的解决方案使用屏幕外缓冲区,但是再次:对blob的大小没有帮助。您确实可以使用屏幕外缓冲区来绘制一个比草图窗口大的图像,但这只是你想要的一半。如果你的斑点仍然很小,那么保存这种方法是没用的!
所以,我的建议是先修复 Thing One ,然后想出一个生成更大blob的算法。然后我们可以谈论缩放和导出为图像,一旦算法运行,这将非常容易。