2018년 9월 디자인과 코딩을 함께 다루는 유튜브 채널을 열었습니다. "타입과 미디어" 사이트는 당분간 유지할 계획이지만, 새로운 정보는 유튜브 비디오를 통해서 소개하겠습니다. 많은 관심 부탁드립니다! — 정대인

파일로 저장하기

세부 목차

이미지 파일로 저장

saveFrame

saveFrame("render-######.tga");

프로세싱으로 만든 애니메이션을 이미지 파일로 저장할 때, saveFrame()을 사용할 수 있습니다. 프로세싱 자체에는 화면의 내용을 바로 비디오로 출력하는 기능은 없습니다. saveFrame()을 이용해서 먼저 이미지 시퀀스로 저장한 이후에, 비디오 편집 소프트웨어를 이용해서 비디오 파일로 합칠 수 있습니다. 화면의 모든 내용을 이미지로 저장하고 싶다면, draw() 함수의 가장 끝부분에 위의 코드를 추가하면 됩니다. 큰 따옴표 안에 파일의 이름을 지정하고 # 심볼을 추가해서 프레임 숫자의 포맷을 정할 수 있습니다. 위의 경우에는 render-000001.tga, render-000002.tga, render-000003.tga, 이렇게 순차적으로 이미지가 스케치 폴더 내에 저장됩니다.

.tif, .tga, .jpg, .png 등의 파일포맷을 지원합니다. .tga는 무손실 이미지 포맷으로, 각 이미지의 크기는 커지지만, 스케치의 실행 속도가 크게 느려지지 않습니다. .png를 사용하면 각 파일의 크기는 작아지나, 스케치의 속도에 더 영향을 줍니다. ‘.jpg’은 손실 압축 포맷으로 간단하게 테스트해보는 용도로 적합합니다.

save

save("image.tga");

화면을 이미지 시퀀스가 아닌 한 장의 이미지로 저장할 때 ‘save()’를 사용합니다. 지원하는 파일 포맷은 위의 saveFrame()과 동일합니다. 애니메이션 스케치에서 어느 한 순간만을 저장하고 싶을 때, mousePressed() 안에 save()를 넣어주면, 원하는 프레임만 저장할 수 있습니다.

영상으로 저장

프로세싱 Movie Maker 메뉴 사용

프로세싱으로 저장한 이미지 시퀀스는 Tools > Movie Maker 메뉴를 통해서 비디오 파일로 변환할 수 있습니다.

외부 영상 편집 소프트웨어 사용

영상에 대한 편집이 필요한 경우에는, After Effects, Premiere Pro, Final Cut Pro 등의 소프트웨어를 사용해서 비디오 파일로 변환할 수 있습니다.

PDF 파일로 저장

프로세싱의 그리기 함수들은 기본적으로 벡터 방식이기 때문에, 화질손실 없이 PDF 파일로 출력하고, 필요에 따라 벡터 이미지 소프트웨어에서 추가적인 편집이 가능합니다. 프로세싱에서 출력한 PDF 파일은 고해상도 인쇄 또한 가능합니다. 프로세싱 메뉴 File > Examples... 에서 Libraries > pdf 안에 여러가지 예제들을 참고하세요. 아래 예제들은 프로세싱 공식 예제들을 바탕으로 여러가지 상황에 따른 pdf 출력 방법을 설명하겠습니다.

창을 열지 않고 PDF 파일 생성

프로세싱을 실행해서 창을 열고 도형들을 표시하는 작업은 컴퓨터의 리소스를 사용합니다. 특히, 화면보다 큰 파일을 저장해야 할 때, 또는, 많은 정보가 들어있는 PDF파일을 저장해야 할 때, 프로세싱 실행창을 열지 않고, 코드가 지시하는 이미지를 그려서 바로 파일로 저장하면 좀 더 작업시간이 짧아집니다.

import processing.pdf.*;

void setup() {
  size(2000, 2000, PDF, "shapes.pdf");
}

void draw() {
  background(255);
  stroke(0, 20);
  strokeWeight(20.0);
  line(0, 0, width, height);
  line(width, 0, 0, height);

  noStroke();
  fill(255, 0, 0);
  ellipse(width/2, height/2, 500, 500);
  
  exit();  // Quit the program
}

첫번째 줄은 pdf와 관련된 기능들을 사용하기 위해서 pdf 라이브러리를 임포트하는 구문입니다. 두번째 size() 함수는 특별히 PDF 모드로 작동하기 위해서 2개의 인수가 추가됩니다. 여기서 생성될 PDF 파일의 이름을 지정해줍니다. 마지막 줄의 exit()은 프로세싱 스케치를 종료하는 함수입니다. 위의 스케치를 실행하면 스케치 폴더 내에 shapes.pdf라는 파일이 생성됩니다. 이 PDF파일은 일러스트레이터와 같은 소프트웨어에서 열고, 추가적인 편집을 할 수 있습니다.

원하는 프레임 저장하기

만약, 우리의 스케치가 계속해서 변화하고 있을 때, 원하는 프레임만 선택해서 PDF파일로 저장할 수 있습니다. beginRecord()endRecord() 사이에 포함되지 않은 내용은 비록 실행창에서는 보일지라도, PDF파일에는 포함되지 않으므로 주의해야 합니다. 마우스를 클릭해서 PDF파일을 저장한 경우에 제대로 저장이 되었는지 따로 알려주지는 않습니다. 따라서, endRecord() 다음에 println() 함수를 이용해서 콘솔창에 저장이 되었다는 메시지를 띄우면 도움이 됩니다.

import processing.pdf.*;

boolean doSave = false;

void setup() {
  size(600, 600);
  frameRate(24);
}

void draw() {
  if(doSave == true) {
    beginRecord(PDF, "shapes.pdf"); 
  }
  
  background(255);
  stroke(0, 20);
  strokeWeight(20.0);
  line(mouseX, 0, width-mouseY, height);
  
  noStroke();
  fill(255, 0, 0);
  ellipse(mouseX, mouseY, 200, 200);
  
  if(doSave == true) {
    endRecord();
    println("pdf saved!");
    doSave = false; 
  }
}

void mousePressed() {
  doSave = true; 
}

위의 스케치는 마우스를 클릭할 때마다 shapes.pdf라는 파일을 생성합니다. 이미 그 파일이 존재하는 경우에는, 새로운 내용으로 덮어쓰기합니다. 만약, 덮어쓰기를 하지 않고, 매 번 클릭할 때마다 새로운 파일을 생성하고 싶다면, shapes.pdf라고 파일이름을 지정해주는 대신에 변수를 사용할 수 있습니다.

beginRecord(PDF, "shapes_" + frameCount + ".pdf");

draw() 함수 내의 beginRecord()를 위와 같이 변경하면, 마우스를 클릭할 때마다 shapes_132.pdf와 같이 현재의 프레임카운트를 사용해서 파일이 저장됩니다. 물론, 스케치를 종료한 이후 다시 실행하면, 프레임카운트는 다시 0부터 시작하기 때문에 파일이 덮어써지게 될 확률도 존재합니다.

누적된 결과 저장하기

스케치에 따라서 background()를 호출하지 않고, 누적된 그래픽을 결과물로 사용해야 할 때가 있습니다. 이런 경우에는, 먼저 setup()에서 beginRecord()를 호출하여 첫 프레임부터 모든 프레임의 내용이 PDF에 계속해서 누적이 되도록 하고, 원하는 프레임에서 endRecord()를 사용하여 PDF 생성을 마치면 됩니다. beginRecord()endRecord()는 언제나 쌍으로 함께 사용해야하며, 그렇지 않을 경우에는 파일이 생성되더라도 내용이 제대로 보이지 않습니다.

import processing.pdf.*;

boolean stopRecording = false;

void setup() {
  size(600, 200);

  beginRecord(PDF, "render.pdf");
}

void draw() {
  fill(0, random(255), random(100, 200));
  float eSize = random(20, 50);
  ellipse(random(width), random(height), eSize, eSize);

  if (stopRecording) {
    endRecord();
    exit();
  }
}

void keyPressed() {
  if (key == ' ') stopRecording = true;
}

여러 페이지 저장하기

여러 페이지 생성

고해상도 이미지 저장하기

고해상도 이미지를 만드는 방법으로, 프로세싱에서 PDF 파일로 출력을 한 후에, 일러스트레이터와 같은 벡터 그래픽스 소프트웨어에서 편집하는 방법이 있습니다. 프로세싱에서 우리가 사용하는 그리기 함수들은 벡터 기반이기 때문에, 화질에 손실 없이 크게 만드는 것이 가능합니다.

만약 프로세싱 자체에서 고해상도 이미지를 뽑아야 할 경우에는, 우리가 만드려는 이미지가 모니터 해상도보다 커지는 경우가 발생합니다. 예를 들어서 size(2000, 3000), 이런 식으로 실행한다면, 모든 픽셀을 한 화면에 보여줄 수 있는 모니터는 많지 않을 것입니다. 또한 그렇게 큰 해상도로 작업하는 것은, 실행 속도에도 큰 영향을 미치게 됩니다. 이를 해결하기 위해서 우리가 확인가능한 작은 해상도로 작업한 후에, 최종 출력을 할 때에만 비율에 맞춰서 고해상도로 출력하는 것이 가능합니다.

float scaleFactor = 1;
int w = 400;
int h = 600;

int numCircles = 20;
int[] xs;
int[] ys;

void setup() {
  size( int(w*scaleFactor), int(h*scaleFactor) );
  
  xs = new int[numCircles];
  ys = new int[numCircles];
  
  for (int i = 0; i < numCircles; i++) {
    xs[i] = (int) random(w);
    ys[i] = (int) random(h);
  }
}

void draw() {
  scale(scaleFactor);
  
  background(120);
  for (int i = 0; i < numCircles; i++) {
    ellipse(xs[i], ys[i], 50, 50);
  }
}

위의 예제에서 실행 창의 크기는 scaleFactor 변수의 값에 비례합니다. 세 배로 큰 실행 창을 만들고 싶으면, float scaleFactor = 3;라고 적어주면 됩니다. 또한, draw() 함수의 마지막에:

void draw() {
  // 생략

  saveFrame();
  exit();
}

이런 식으로 추가하면, 커다란 실행 창에 원하는 이미지를 그리고, 그 프레임을 저장한 다음에, 스케치는 바로 종료됩니다.

위의 예제는 스케치에 변화가 없을 경우에만 적용이 가능합니다. 만약 스케치에 애니메이션이나 인터렉션이 들어있어서 실행 중간에 고해상도의 이미지를 출력해야한다면, PGraphics를 사용하여 따로 이미지를 만들어주는 방법이 있습니다.

파일 이름 구성하기

프로세싱에서 이미지나 PDF 파일 등을 생성할 때, 특정 파일이름을 지정해주면, 저장할 때마다 같은 이름을 가진 파일을 덮어쓰기 때문에 변화하는 결과를 여러 파일로 저장하기 힘듭니다. 그럴 경우에는, 파일이 저장되는 시간에 맞추어서 파일이름을 다르게 지정해주면, 파일이 덮어써지는 일을 방지할 수 있습니다.

void setup() {
  size(200, 200);
}

void draw() {
  background(random(255), random(255), random(255));
  ellipse(width/2, height/2, 50, 50);
}

void mousePressed() {
  save( timestamp() + ".png" );
}

String timestamp() {
  return year() + nf(month(), 2) + nf(day(), 2) + "-"  + nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
}

위의 예제를 실행하면, 마우스를 클릭할 때마다 당시의 시간을 바탕으로 만들어진 문자열을 파일이름으로 해서 PNG 파일을 저장합니다. 마우스를 여러 번 클릭해도 계속해서 시간을 바탕으로 새로운 파일을 만들어줍니다. 물론, 이 경우에도 초 단위 이하로 마우스를 클릭하게 되면 파일이 덮어써지게 될 수 있습니다.

텍스트 파일로 저장

PrintWriter

XML 파일로 저장

XML은 <tag>를 사용하는 점에서 HTML과 비슷합니다.

자바스크립트 오브젝트로 저장

JSON 파일은 다른 프로그램과 데이터를 주고받기에 적합한 파일입니다.