高分辨率处理输出

我正在寻找有关编程语言/环境处理的帮助。

我对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  -1 && mouseX  -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,但这对我来说没有用,至少在我正在使用的代码的上下文中是这样。 以下是论坛中的一段代码,演示了一个用户以高分辨率保存Processing输出输出的方法:

 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  -1 && mouseX  -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; } } 

编辑:两个屏幕截图,比较实施乔治白色背景解决方案之前和之后的不同视觉效果:

之前 后

除了Kevin的答案之外,您还可以使用JVisualVM查看花费大部分CPU时间的位置。 在不同时间对CPU进行采样和分析后,大部分时间都是计算RGB值:

jvisualvm screenshot1

jvisualvm screenshot2

jvisualvm screenshot3

在优化时最好从占用大部分CPU的function开始。

这是草图的一个版本,它使用默认的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); } 

以下是我可以保存的内容:

结果1

结果2

结果3

更新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或Gray Scott反应扩散模拟:

youtube视频预览

查看Daniel Shiffman的video教程 :它将帮助您更好地理解算法并编写更高效的实现。

丹尼尔希夫曼反应扩散

我想到了一些更加强硬的方法:

  1. 在GPU上并行化任务,将算法重写为Processing GLSL着色器(PShader) - 另外,如果你不介意稍微不同的实现,可能更容易调整Shadertoy反应扩散片段着色器作为PShaders运行(例如这个或者这一个 )
  2. 并行化CPU上的任务(请参阅Java多处理 资源 - sorta干燥材料)

着色玩具反应扩散1

着色玩具反应扩散2

你真的在谈论两件不同的事情:

第一件事:让彩色斑点更大。 这有点烦人,因为算法使用像素数组,因此它不像调用scale()函数那么简单。

实际上,因为算法适用于像素,所以任何改变分辨率的简单方法都会变得像素化。

像素化

您在论坛上获得的解决方案是绘制到屏幕外缓冲区,这实际上不会改变blob的大小。 更改blob大小的唯一方法是更改​​算法。

你可能能够修改你操作数组的方式,以便blob更大,但老实说,我并不完全理解数组现在正在做什么,这使得它很难提供帮助。

第二件事:导出为图像。

最简单的方法是简单地调用save("ImageNameHere.png")函数。 这将创建一个与草图大小相同的图像,其中包含调用函数时屏幕上显示的内容。

您在论坛上找到的解决方案使用屏幕外缓冲区,但同样: 这对blob的大小没有帮助。 您确实可以使用屏幕外缓冲区绘制到比草图窗口大的图像,但这只是您想要的一半。 如果你的斑点仍然很小,那么保存这种方法是没用的!

所以,我给你的建议是先修复Thing One ,然后想出一个生成更大blob的算法。 然后我们可以谈论缩放和导出为图像,一旦你的算法工作,这将非常容易。