高分辨率处理输出

时间:2016-10-31 21:11:37

标签: java graphics processing resolution high-resolution

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

我对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;
  }
}

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

Before After

2 个答案:

答案 0 :(得分:2)

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

jvisualvm screenshot1

jvisualvm screenshot2

jvisualvm screenshot3

最好从优化时占用大部分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);
}

以下我可以保存的内容:

result 1

result 2

result 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 or Grey Scott reaction diffusion模拟:

youtube video preview

查看Daniel Shiffman's video tutorial on it:它将帮助您更好地理解算法并编写更高效的实现。

Daniel Shiffman Reaction Diffusion

还有一些更加强硬的方法可以让人想到:

  1. 在GPU上并行化任务,将算法重写为Processing GLSL shader (PShader) - 另外,如果您不介意稍微不同的实现,可能更容易调整Shadertoy reaction diffusion fragment shaders作为PShaders运行(例如this onethis one
  2. 在CPU上并行执行任务(请参阅Java Multiprocessing resources - sorta dry material)
  3. shader toy reaction diffusion 1

    shader toy reaction diffusion 2

答案 1 :(得分:1)

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

Thing One:让彩色斑点更大。这有点烦人,因为算法使用像素数组,所以它不像调用scale()函数那么简单。

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

pixelated

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

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

事情二:导出为图片。

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

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

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