Code for Photo-booth

// Photo-Booth with Processing
// Markku Nousiainen, 2014


int pictureSet = 80; // Where to start the numbering of images.

int picturesForCombo = 4;
int pictureXPixels = 2352; // The size of the screen and the images from the camera are stored here.
int pictureYPixels = 1568; 
int marg = 25;
boolean startTakingPictures= false;

boolean waitInTheBeginning = false;
boolean waitInTheEnd1 = false;
boolean waitInTheEnd2 = false;
int waitInTheBeginningTime = 4000;
int waitInTheEnd1Time = 15000;
int waitInTheEnd2Time = 20000;
int pictureInterval = 0; // An extra waiting time between the shots.


PImage[] picture = new PImage[picturesForCombo];
PImage combo = createImage(pictureYPixels, pictureXPixels, RGB);

String picturePath = "/ENTER YOUR PATH FOR SAVING THE IMAGES HERE/";
String printPath = "/ENTER YOUR PATH FOR PRINTING HERE/";

String pictureName = "";

PImage textBoard1 = loadImage("/ENTER YOUR PATH HERE/textBoard1.jpg");
PImage textBoard2 = loadImage("/ENTER YOUR PATH HERE/textBoard2.jpg");
PImage textBoard3 = loadImage("/ENTER YOUR PATH HERE/textBoard3.jpg");
PImage textBoard4 = loadImage("/ENTER YOUR PATH HERE/textBoard4.jpg");

void setup()
{
  size(displayWidth, displayHeight); 
  background(255);
  combo.loadPixels();
  for (int i = 0; i < (combo.width * combo.height); i++){  // We initialize the combo picture white.
   combo.pixels[i] = color(255); 
  }
  combo.updatePixels();
  initializeCamera();
}

void draw() {
  
  if (waitInTheBeginning) {   // In the beginning we show the instructions screen.
    delay(waitInTheBeginningTime);
    waitInTheBeginning = false;
    startTakingPictures = true;
  }
  else if (waitInTheEnd1) {
    delay(waitInTheEnd1Time);
    waitInTheEnd1 = false;
    waitInTheEnd2 = true;
    startTakingPictures = false;
    emptyTheScreen();
    image(textBoard4, 0, 0);
  }
  else if (waitInTheEnd2) {
    delay(waitInTheEnd2Time);
    waitInTheEnd2 = false;
    startTakingPictures = false;
  }
  
  if (startTakingPictures) {  
    for (int i = 0; i < picturesForCombo; i++) {
      pictureName = picturePath + "set" + leadingZeros(pictureSet, 5) + "picture" + str(i) + ".jpg";
      getPicture(pictureName);
      picture[i] = loadImage(pictureName);
      picture[i] = turnToVertical(picture[i], true);
      picture[i].save(pictureName);
      delay(pictureInterval);
    }
    combo.copy(picture[0], 0, 0, pictureYPixels, pictureXPixels, 0, 0, ((pictureYPixels/2) - marg), 
      ((pictureXPixels/2) - marg));
    combo.copy(picture[1], 0, 0, pictureYPixels, pictureXPixels, ((pictureYPixels/2) + marg), 0, 
      ((pictureYPixels/2) - marg), ((pictureXPixels/2) - marg));
    combo.copy(picture[2], 0, 0, pictureYPixels, pictureXPixels, 0, ((pictureXPixels/2) + marg), 
      ((pictureYPixels/2) - marg), ((pictureXPixels/2) - marg));
    combo.copy(picture[3], 0, 0, pictureYPixels, pictureXPixels, ((pictureYPixels/2) + marg), 
      ((pictureXPixels/2) + marg), ((pictureYPixels/2) - marg), ((pictureXPixels/2) - marg));
    
    // Let's copy the combo image to the screen.
    emptyTheScreen();
    image(textBoard3, 0, 0);
    copy(combo, 0, 0, pictureYPixels, pictureXPixels, (displayWidth / 2), 0, 
      ((pictureYPixels * displayHeight) / pictureXPixels), displayHeight);
    
    // Next we'll save the combo image.
    pictureName = printPath + "combo" + leadingZeros(pictureSet, 5) + ".jpg";
    combo.save(pictureName);
    
    pictureSet = pictureSet + 1;
    startTakingPictures = false; // We'll be waiting for the next time a key is pressed.
    waitInTheEnd1 = true;
  }
  else if ((!(waitInTheEnd1)) && (!(waitInTheEnd2))) {  
    // The system is in a state in which pictures are not taken neither displayed 
    //  neither a finishing text board is displayed. So an input is expected from the user.
    if (keyPressed) {                                   
      waitInTheBeginning = true;
      emptyTheScreen();
      image(textBoard2, 0, 0);
    }
    else {   // We're not taking pictures yet, instead an info text is displayed on the screen.
      emptyTheScreen();
      image(textBoard1, 0, 0);
    }
  }

}

boolean sketchFullScreen() {  
  // This method is used to open the sketch automatically in full screen mode.
  return true;
}

void getPicture(String pictureName) {
  try {
    Runtime rtime = Runtime.getRuntime();
    Process child = rtime.exec("/opt/local/bin/gphoto2 " + "--capture-image-and-download " + 
      "--quiet " + "--filename " + pictureName);
    child.waitFor();
  }
  catch (Exception e) {
    e.printStackTrace();
  }
}

void initializeCamera() {
  try {
    Runtime rtime = Runtime.getRuntime();
    Process child = rtime.exec("killall PTPCamera");
    child.waitFor();
  }
  catch (Exception e) {
    e.printStackTrace();
  }
}


String leadingZeros(int indeksi, int toHowManyDigits) {
  int numbers = (Integer.toString(indeksi)).length(); 
  String leading = ""; 
  switch (toHowManyDigits-numbers) { // Let's put enough zeros in front of the index. 
  case 0:
    break; // No zeros are needed.
  case 1:
    leading = "0";
    break;
  case 2:
    leading = "00";
    break;    
  case 3:
    leading = "000";
    break;
  case 4:
    leading = "0000";
    break;
  case 5:
    leading = "00000";
    break;
  }
  String output = leading + str(indeksi);
  return output;
}

PImage turnToVertical(PImage picture1, boolean upsideToLeft) {
  PImage picture2 = createImage(picture1.height, picture1.width, RGB); 
  // We'll create an image of the same size as picture1 but in vertical orientation.
  color c = color(0, 0, 0);
  picture2.loadPixels();
  if (upsideToLeft) {
    for (int i=0; i=0; j=j-1) {
        c = picture1.get(i, j);
        picture2.set((picture1.height-1-j), i, c);
      }
    }
  }
  else { // The sky (= upside) is to the right.
    for (int i=(picture1.width-1); i>=0; i=i-1) {
      for (int j=0; j