2016-10-31 12 views
2

Я ищу помощь по языку программирования/среде обработки.Выход обработки высокого разрешения

Я довольно новичок в обработке, и я экспериментирую с куском кода от кого-то на openprocessing.org. Мне очень нравятся визуальные результаты, которые дает этот код, и я хотел бы продолжить работу с ним. К сожалению, выход очень низкий. Поэтому я ищу кого-то, кто мог бы помочь мне разобраться, как: а) увеличить размер или разрешение сформированных форм и б) сохранить все как файл 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(); 
} 

До сих пор я экспериментировал с предполагаемым методом с высокой разрешающей способностью, публикуемую в обработке-форума, который не работал для меня, хотя, по крайней мере, не в контексте вышеприведенного кода, с которым я работаю. Вот кусок кода из форума, который демонстрирует путь одного пользователя сохранения выходного выходной обработки в высоком разрешении:

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

Я был бы очень благодарен всем, кто достаточно опытен с обработкой и 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; 
    } 
} 

Edit: Два скриншоты сравнивающих различные визуальные результаты до и после реализации решения Джорджа на белом фоне:

BeforeAfter

+0

Можете ли вы быть более конкретным именно о том, что не работает о второй части кода? Кроме того, какое разрешение вы планируете? Как вы хотите, чтобы эффект масштабировался? –

+0

Спасибо за ваш быстрый ответ! Я попытался реализовать метод сохранения из второго кода в первый (с моим ограниченным знанием о том, как обрабатываются и работает Java). Я добавил модифицированный код к моему первоначальному сообщению выше. К сожалению, сохраненный png не содержит ничего. – JoSch

+0

Какое разрешение вы планируете? Вы хотите, чтобы результат был больше или окно эскиза было больше, или вы хотите, чтобы окно эскиза оставалось неизменным, а просто имело большие капли цвета? Должен ли он экспортироваться как 'pdf', или это нормально экспортировать в качестве файла изображения? –

ответ

1

Вы действительно говорите о двух разных вещах:

Thing One: Изготовление цветных капель больше. Это немного раздражает, потому что алгоритм использует пиксельный массив, поэтому это не так просто, как вызов функции scale().

Фактически, поскольку алгоритм работает с пикселями, любой простой подход к изменению разрешения будет пикселизованным.

pixelated

Решение вы получили на форуме, чтобы привлечь в буфер закадровым, который не будет на самом деле изменить размер сгустков. Единственный способ изменить размер капель - это изменить алгоритм.

Возможно, вы сможете изменить, как вы манипулируете массивами, поэтому капли больше, но, честно говоря, я не совсем понимаю, что сейчас делают массивы, что затрудняет помощь.

Thing Two: Экспортировать как изображение.

Самый простой способ сделать это - просто вызвать функцию save("ImageNameHere.png"). Это создаст изображение с тем же размером, что и ваш эскиз, содержащий все, что показывалось на экране при вызове функции.

Решение, которое вы нашли на форуме, использует буфер вне экрана, но опять же: , который не поможет с размером капель. Вы можете использовать буфер вне экрана для рисования изображения большего размера, чем окно эскиза, но это только половина того, что вы хотите. Сохранение этого способа бесполезно, если ваши капли все еще малы!

Итак, мой совет для вас - исправить Thing One и придумать алгоритм, который генерирует большие капли. Затем мы можем поговорить о масштабировании и экспорте в качестве изображения, что будет довольно легко, если у вас будет работающий алгоритм.

+0

Хорошо. Большое спасибо за вашу помощь до этого момента. Я сяду и попытаюсь получить более полное представление о том, что происходит с массивами здесь, чтобы манипулировать размером с капли. Если вы можете дать мне какие-либо дальнейшие советы или иметь представление о том, как я могу это сделать, это было бы фантастически. Еще раз спасибо, спокойной ночи. – JoSch

+0

Кроме того, как вы думаете, было бы целесообразно опубликовать эту конкретную проблему (создания больших капель или даже создания такого же эффекта с помощью другого метода, а не на пиксельной основе, как в версии, которую я сейчас использую) в качестве новый вопрос здесь о StackOverflow? – JoSch

+0

@JohnGalt Честно говоря, это может быть немного ** слишком широко ** для переполнения стека. Существует множество способов подойти к проблеме, и Stack Overflow не создан для общих вопросов типа «как это сделать». То же самое в большинстве мест в Интернете. Гораздо проще ответить на конкретный вопрос: «Я попробовал X, ожидал Y, но получил Z вместо». –

2

В дополнение к ответу Кевина вы можете использовать JVisualVM, чтобы узнать, где большая часть времени процессора расходуется. После отбора проб и профилирование процессора в разное время на удивление большую часть времени была вычисления значений RGB:

jvisualvm screenshot1

jvisualvm screenshot2

jvisualvm screenshot3

Лучше всего начать с функциями принимать большинство из CPU при оптимизации.

Вот версия эскиза, который использует диапазон RGB по умолчанию 0-255 и вычисляет значение 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 

Update : Вот модифицированная функция, которая отображает значения так, фон белый:

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

Update 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"); 
    } 
} 

К сожалению, у меня нет времени чтобы получить более подробную информацию и предоставить быстрое рабочее решение, но я могу предоставить некоторые указатели tha т может помочь:

Это выглядит упрощенной 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 one или this one)
  2. Распараллеливание задачи на CPU (см Java Multiprocessingresources - Сорта сухой материал)

shader toy reaction diffusion 1

shader toy reaction diffusion 2

+0

Привет. Джордж. Также огромное спасибо вам за все входные данные! Я собираюсь пройти через все это сегодня и опубликовать здесь снова, как только я натолкнулся на любые полезные результаты моей текущей проблемы. – JoSch

+0

Данг Джордж. Я всегда люблю ваши ответы. Я почти не пробовал ответить на этот вопрос, потому что знал, что ты придешь с чем-то, что выдуло мою воду! –

+0

Привет, Джордж, я продолжаю работать, может пройти через код, а также все ресурсы, которые вы предоставили с большими надеждами на то, что в конечном итоге это выдумаете.У меня есть небольшой вопрос, который вы могли бы мне помочь, так как я еще не получил полного понимания кода. Как вы думаете, есть ли способ изменить цвет фона (в настоящее время серый) на белый или даже прозрачный? Или, может быть, вы можете просто указать мне, где в коде определяется цвет фона. Я еще не понял. Еще раз спасибо всем за помощь. – JoSch

 Смежные вопросы

  • Нет связанных вопросов^_^