🔍

the infinite poster in Processing

Processing IDE is currently not associated with generative AI. Together with a locally installed A1111/Stable Diffusion, we have a powerful, easy to program, designer- and artist friendly toolchain to work with.

infinite poster screenshot I
infinite poster screenshot III

This particual prototype comes with a pretty simple idea: We have a big canvas, that is procedually filled with graphics coming from a generative call of a local Stable Diffusion/A1111 API. The prompt and the render size is randomly composed with some arrays and simple randoms. Your turn 🙂

import processing.data.JSONArray;
import processing.data.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.codec.binary.Base64;


String[] arr = {"Han Chinese", "Indian", "European", "African", "Arab", "Southeast Asian", "Hispanic", "Bengali", "Russian", "Japanese", "Persian", "Korean", "Turkish", "Vietnamese", "Malay", "Filipino", "Thai", "Pakistani", "Mexican", "Egyptian", "German", "French", "Italian", "Ethiopian", "Burmese", "Hausa", "Yoruba", "Nigerian", "Vietnamese", "South African", "Filipino", "Tanzanian", "Iranian", "Turkish", "Iraqi", "Polish", "Ukrainian", "British", "Pakistani", "Bangladeshi", "Indonesian", "Ukrainian", "Maasai", "Mexican", "Japanese", "Chichewa", "Ugandan", "Moroccan", "Algerian", "Tunisian", "Zulu", "Malian", "Senegalese", "Somalian", "Ivory Coast", "Malagasy", "Cuban", "Syrian", "Sudanese", "Ghanaian", "Angolan", "Cameroonian", "Sri Lankan", "Uzbek", "Romanian", "Malian", "Burkina Faso", "Chilean", "Moroccan", "Ugandan", "Kazakh", "Nepali", "Tajik", "Bosnian", "Haitian", "Belarusian", "Dominican", "Latvian", "Armenian", "Lithuanian", "Papua New Guinean", "Namibian", "Macedonian", "Slovenian", "Kosovo", "Bruneian", "Belizean", "Bahraini", "Maldivian", "Eritrean", "Guyanese", "Surinamese", "Fijian", "Tongan", "Solomon Islands", "Luxembourgish", "Montenegrin", "Bhutanese", "Djiboutian", "Saami", "Tuareg", "Andamanese", "Tibetan", "Ainu", "Uighur", "Tuareg", "Andamanese", "Nubian", "Guarani", "Basque", "Mestizo", "Romani"};

String[] arr2 = {"female", "male", "man" , "boy" ,"child", "grandpa","grandma","teenager", "lady","old man","old lady",  "androgyn person", "transgender person", "teenager","fat male", "ugly person", "sick person"};

String[] arr3 = {"forest","dump","street corner","pub","home","street","bed","dancefloor","hospital","battlefield","ruins","boat","lake","river", "protest march", "graveyard", "prison", "beach", "school","studio","office","boxing gym","junkyard"}; 

String[] arr4 = {"paranoid", "in pain","euphoric","depressed","enjoyed","concerned","drunken","dying","amused","neutral","bored","overjoyed", "excited" };

String[] arr5 = {"eyes closed","mouth open","looking up","looking down","showing teeth","laughing", "eyes wide open", "looking sceptical", "arrogant", "distanced"};

String[] doings ={ "working","observing","sleeping","protesting","enjoying","walking","sitting","jumping","waiting" };

String[] jobs ={ "teacher","soldier","nurse","ceo","stripper","junkie","officer","social worker","bum","programmer","mother", "father", "housewife","thug"};

PImage img;
PGraphics canvas;


PImage shadeimg;

PImage brush_img;

int dimens = 256;

int pad = 40;

int lastExecutionFrame = 0;
int executionInterval = 1 * 1; // 5 seconds (assuming 60 frames per second)

String current_prompt = "";

PFont font;
 


PImage polaroid_bg;

void setup() {
  size(1000, 500);
   frameRate(1);
  canvas = createGraphics(4000, 2000);
  canvas.imageMode(CENTER);
  
  shadeimg = loadImage("shade.png");
  polaroid_bg = loadImage("polaroid.png");

  callSD();
  
  font = createFont("singleday.ttf",40);
  textFont(font, 40);
  
}

void draw() {
  background(255);

  if (brush_img != null) {
    
   // dimens=512;
    
    // how many times does the image fit in the relevant range?
    float xratio = (canvas.width - pad - dimens*.5 )/  (dimens);
    float yratio = (canvas.height - pad - dimens*.5 )/  (dimens);
 
     xratio -=1;
     yratio -=1;
      
    // do the distribution
    int rx = int(  ( random(xratio)   )) * dimens ; 
    int ry  = int( ( random(yratio)   )) * dimens ; 
    
    // add the padding
    rx += pad + dimens/2;
     ry += pad + dimens/2;
    
    float ra = random(1)-.5;
    ra*=.11;
    canvas.beginDraw();
    // canvas.filter(SHADOW);
    
    canvas.pushMatrix();
     canvas.translate(rx,ry);
     
    canvas.rotate(ra);
    // canvas.image(shadeimg, -2,-2,dimens+40,dimens+40);
      canvas.image(polaroid_bg, 0,0);
      canvas.textFont(font, 48);
     
    canvas.image(brush_img, 0,0);
 
     canvas.fill(11);
    canvas.textAlign(CENTER);
   // canvas.fontStyle(BOLD);
    canvas.textSize(38);
    canvas.text(current_prompt, 0, dimens/2+62);
    //canvas.image(brush_img, canvas.width - rx - 500, ry);
    canvas.popMatrix();
    canvas.endDraw();
    
}

  image(canvas, 0, 0, width, height);
  
  /*
  fill(111);
  textSize(22);
  text(current_prompt,10,10);
  */
  
   // Check if 5 seconds have passed since the last execution
  if (frameCount - lastExecutionFrame >= executionInterval) {
    // Call your function here
    callSD();

    // Update the last execution frame
    lastExecutionFrame = frameCount;
  }
}

void callSD() {
  
//  dimens = 128 * ((int)random(2)+3);
   dimens = 512;
  
  String cultura = arr[(int)(random( arr.length))];
  String persona = arr2[(int)(random( arr2.length))];
  String locationa =   arr3[(int)(random( arr3.length))];
   String mooda =   arr4[(int)(random( arr4.length))];
   
   String facial_express =   arr5[(int)(random( arr5.length))];
   
   String job = jobs[(int)(random( jobs.length))];
   
   String c_doing = doings[(int)(random( doings.length))];
  
 //println(persona + "//" + cultura + " // " + locationa);
 

  
  // Create a JSON object with the required data
  JSONObject requestData = new JSONObject();
  requestData.setString("prompt",
  
  "analog polaroid black white photography of , ( " + 
  cultura +"  " +  mooda + " " + persona +" " +  job + " "+ c_doing +" "+ facial_express + " mood , in " + locationa
   +
  " :1.2) , colorful,  4k 8k, kodak, bokeh,   glossy cute,  <lora:epi_noiseoffset2:0.4>, white border"
  );
  
  
   current_prompt =  "me, " + mooda + " in the " + locationa;
  
  requestData.setString("negative_prompt", "ugly, 1girl,  illustration, render, deformed, deformed iris, sexy, tits, breast,beautiful");
  requestData.setInt("width", dimens);
  requestData.setInt("height", dimens);
  requestData.setInt("steps", 16);

  // Convert JSON object to a string
  String jsonString = requestData.toString();

  // Define the API endpoint
  String apiEndpoint = "http://127.0.0.1:7860/sdapi/v1/txt2img";

  try {
    // Create URL object
    URL url = new URL(apiEndpoint);

    // Open connection
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

    // Set request method
    connection.setRequestMethod("POST");

    // Set request headers
    connection.setRequestProperty("accept", "application/json");
    connection.setRequestProperty("Content-Type", "application/json");

    // Enable input/output streams
    connection.setDoOutput(true);

    // Write data to the server
    try (java.io.OutputStream os = connection.getOutputStream()) {
      os.write(jsonString.getBytes("UTF-8"));
    }

    // Get response code
    int responseCode = connection.getResponseCode();

    // Check if the request was successful (HTTP 200 OK)
    if (responseCode == HttpURLConnection.HTTP_OK) {
      // Read the response
      InputStream is = connection.getInputStream();
      StringBuilder response = new StringBuilder();
      int charRead;
      while ((charRead = is.read()) != -1) {
        response.append((char) charRead);
      }
      is.close();

      // Handle the response
      JSONObject responseObject = parseJSONObject(response.toString());
      JSONArray imagesArray = responseObject.getJSONArray("images");

      // Assuming the "images" array contains only one item
      String base64Image = imagesArray.getString(0);

      // Decode base64 to byte array
      byte[] imageBytes = Base64.decodeBase64(base64Image);

      // Create a temporary file
      File tempFile = File.createTempFile("temp", ".png");

      // Write the byte array to the temporary file
      try (FileOutputStream fos = new FileOutputStream(tempFile)) {
        fos.write(imageBytes);
      }

      // Load the image from the temporary file
      img = loadImage(tempFile.getAbsolutePath());
      brush_img = img;

      if (img != null) {
        // Now the image is fully loaded, you can display it
        
      } else {
        println("Failed to load image.");
      }

      // Delete the temporary file
      tempFile.delete();
     
    } else {
      println("HTTP request failed with response code: " + responseCode);
    }

    // Disconnect the connection
    connection.disconnect();
  } catch (Exception e) {
    e.printStackTrace();
  }
}



void keyPressed() {
  if (key == 'p' || key == 'P') {
    // Generate a timestamp
    String timestamp = year() + nf(month(), 2) + nf(day(), 2) + nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2);
    
    // Save the PGraphics to disk with a timestamped filename
    String filename = "out/ip_" + timestamp + ".png";
    canvas.save(filename);
    println("Saved as: " + filename);
  }
}