• fullscreen
  • Brush.pde
  • DynamicLoader.pde
  • collaborativeDrawing.pde
  • class Brush {
      color c[];
      int colnum = 0;
      PVector pos, ppos;
      float pw, w, pd, d, theta, ptheta;
      float x1, y1, x2, y2, px1, px2, py2, py1;
      PVector one, two;
      boolean pencil = false;
    
      PImage pollockColors;
    
      PGraphics mapa;
    
    
      ArrayList vals;
    
      void changeColor() {
    
        colnum = (int)random(c.length);
    
    
        mapa = createGraphics(512, 512, JAVA2D);
        mapa.beginDraw();
        for (int i =0 ;i<1000;i++) {
          //mapa.rect(127, random(80, 125),10,10);
          mapa.stroke(127);
          mapa.line(random(10, mapa.width-10), random(10, mapa.height-10), random(10, mapa.width-10), random(10, mapa.height-10));
        }
        // mapa.filter(BLUR,1);
        mapa.endDraw();
      }
    
      Brush() {
    
    
        pollockColors = loadImage("pollocki.jpg");
        pollockColors.loadPixels();
        //src.filter(GRAY);
        c = new color[2000];
        for (int i = 0;i<c.length;i++) {
          c[i] = pollockColors.pixels[(int)random(pollockColors.pixels.length)];
        }
    
        changeColor();
        pos = new PVector(width/2, height/2, 0);
        ppos = new PVector(width/2, height/2, 0);
        w = random(2, 10);
        d = 0;
    
    
    
    
    
    
        theta = ptheta = 0;
    
        one = new PVector(0, 0);
        two = new PVector(0, 0);
      }
    
      void update() {
    
        pos.x += (mouseX-pos.x)/2.5;
        pos.y += (mouseY-pos.y)/2.5;
        ppos.x += (pmouseX-ppos.x)/2.5;
        ppos.y += (pmouseY-ppos.y)/2.5;
    
    
        d += (dist(pos.x, pos.y, ppos.x, ppos.y) - d) / 10.0;
    
        theta = atan2(ppos.y-pos.y, ppos.x-pos.x);
    
    
        pushMatrix();
        translate((pos.x+ppos.x) *.5, (pos.y+ppos.y) *.5);
    
    
        x1 = screenX(cos(theta+QUARTER_PI)*d, sin(theta+QUARTER_PI)*d);
        y1 = screenY(cos(theta+QUARTER_PI)*d, sin(theta+QUARTER_PI)*d);
    
        x2 = screenX(cos(theta-QUARTER_PI)*d, sin(theta-QUARTER_PI)*d);
        y2 = screenY(cos(theta-QUARTER_PI)*d, sin(theta-QUARTER_PI)*d);
    
    
        popMatrix();
    
        //postUpdate();
    
        //autobrush();
        // paint();
      }
    
      void postUpdate() {
    
    
        px1 = x1;
        py1 = y1;
    
        px2 = x2;
        py2 = y2;
      }
    
      void autobrush() {
        pos.x = noise(frameCount/30.0)*width*2-width/2;
        pos.y = noise(frameCount/32.0)*height*2-height/2;
        paint();
        ppos.x=pos.x;
        ppos.y=pos.y;
      }
    
      void paint() {
    
        if (pencil) {
    
          fill(0, 120);
          noStroke();
          quad(
          x2, y2, 
          px2, py2, 
          px1, py1, 
          x1, y1
            );
        }
        else {
    
          pushStyle();
          imageMode(CENTER);
          pushMatrix();
          translate(pos.x, pos.y);
          rotate(theta);
          tint(c[colnum], 10);
          image(mapa, 0, 0, d*3, d*3);
          popMatrix();
          popStyle();
    
          noStroke();
          fill(c[colnum], 120);
    
          quad(
          x2, y2, 
          px2, py2, 
          px1, py1, 
          x1, y1
            );
    
    
    
          stroke(c[colnum], 140);
          line(x2, y2, px2, py2);
          stroke(c[colnum], 40);
          line(x1, y1, px1, py1);
        }
      }
    }
    
    
    class DynamicLoader implements Runnable {
      PApplet parent;
      
    
      DynamicLoader(PApplet _parent) {
        parent = _parent;
      }
      void run() {
        loadLast();
      }
    
    
      void loadLast() {
    
    
        URL test;
        try {
          test = new URL(lastScript);
    
          try {
            URLConnection yc = test.openConnection();
    
    
            BufferedReader in = new BufferedReader(new InputStreamReader(
            yc.getInputStream()));
            String inputLine;
            while ( (inputLine = in.readLine ()) != null) {
              output.add(inputLine);
            }
    
            in.close();
          }
          catch(IOException ee) {
          }
        }
        catch(MalformedURLException e) {
        }
    
        if (output.size()>0) {
          int c = 0;
          for (int i = 0 ; i < output.size();i++) {
            String name = (String)output.get(i);
            if (debug)
              println(name);
            c = i;
          }
    
          if (debug)
            println("got first image!");
          String path = (String)output.get(0);
          source = loadImage("http://lab19.dyndns.org/"+path);
          
          
          loaded = true;
        }
    
    
    
        if (source!=null) {
          image(source, 0, 0);
        }
      }
    
    
      void saveit() {
    
        display();
    
    
    
       // ImageToWeb img = new ImageToWeb(parent);
       // img.setType(ImageToWeb.PNG);
       // byte[] tmp = img.getBytesTIFF(buffer);
        //img.save("gif",true);
        byte[] tmp = getBytes();
        post(folder, url, "souvenir_by_kof.png", true, tmp);
        
        saved = true;
        
        
      }
      
      
      
    
    
    void post(String project, String url, String filename,  boolean popup, byte[] bytes)
      {
        
        String cType = "image/png";
        String  imageType = "png";
        
        String boundary = "|X-seltars-image-and-pdf-byte-array-uploader-X|";
        try{
          URL u = new URL(url);
          HttpURLConnection c = (HttpURLConnection)u.openConnection();
    
          // post multipart data
          c.setDoOutput(true);
          c.setDoInput(true);
          c.setUseCaches(false);
    
          // set request headers
          c.setRequestProperty("Content-Type", "multipart/form-data; boundary="+boundary);
    
          // open a stream which can write to the url
          DataOutputStream dstream = new DataOutputStream(c.getOutputStream());
    
          // write content to the server, begin with the tag that says a content element is comming
          dstream.writeBytes("--"+boundary+"\r\n");
    
          // discribe the content
          dstream.writeBytes("Content-Disposition: form-data; name=\""+project+"\"; filename=\""+filename+"\"\r\nContent-Type: "+cType+"\r\nContent-Transfer-Encoding: binary\r\n\r\n");
          dstream.write(bytes,0,bytes.length);
    
          // close the multipart form request
          dstream.writeBytes("\r\n--"+boundary+"--\r\n\r\n");
          dstream.flush();
          dstream.close();
    
          StringBuffer response = new StringBuffer();
          // read the output from the URL
          try{
            BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
            // Get the server response code
            int responseCode = -1;
            try
            {
              responseCode = c.getResponseCode();
            }
            catch (IOException ioe)
            {
            }
            if(responseCode == 200){
              // Everything has gone well so far
              // Get the server response
              String responseLine = null;
              do{
                responseLine = in.readLine();
                if (responseLine != null)
                {
                  response.append(responseLine + "\n");
                  if(responseLine.substring(0,4).equals(("http").substring(0,4))){ // if it's an url
                    if(popup) parent.link(responseLine, "_blank"); 
                  }
                }
              }
              while(responseLine!=null);
              // output the response
              println(response.toString());
            }
          }
          catch(Exception e){
            e.printStackTrace();
          }
        }
        catch(Exception e){
          e.printStackTrace();
        }
      }
      
        public byte[] getBytes(){
        return getBytes(parent.g);
      }
    
      /**
       * Get the given PGraphics bytearray
       * @param src the source graphics
       */
      public byte[] getBytes(PGraphics src){
    
        
          
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          try
          {
            ImageIO.write((BufferedImage)src.getImage(), "PNG", baos);
          }  
          catch (Exception e)
          {
            e.printStackTrace();
            return new byte[0]; // Problem
          }
          return baos.toByteArray();
    
      }
      
    }
    
    class DynamicSaver extends DynamicLoader implements Runnable {
    
      DynamicSaver(PApplet _parent) {
        super(_parent);
      }
    
      void run() {
        saveit();
      }
    }
    
    
    
    
    /**
     *  Collaborative drawing, kof 12
     *
     */
    
    
    import java.io.*;
    import java.awt.image.BufferedImage;
    import javax.imageio.*;
    import javax.imageio.stream.*;
    import java.net.*;
    
    String folder = "testing";
    String url = "http://lab19.dyndns.org/Upload.php";
    String lastScript = "http://lab19.dyndns.org/loadLast.php";
    PGraphics buffer;
    
    Thread loader,saver;
    
    boolean loaded;
    
    boolean paint = false;
    boolean saved = false;
    
    boolean debug = false;
    int refreshInterval = 250;
    
    Thread thread;
    
    
    
    PImage source;
    Brush brush;
    
    
    ArrayList output = new ArrayList();
    
    
    
    
    void setup() {
    
      size(900, 450, P2D);
    
      buffer = createGraphics(width, height, JAVA2D);
    
      buffer.beginDraw();
      buffer.background(0);
      buffer.endDraw();
    
      brush = new Brush();
    
      //smooth();
    
      background(255);
    
    
      textFont(loadFont("53Seed-8.vlw"));
      textMode(SCREEN);
      //System.getSecurityManager().checkPermission(new SocketPermission("lab19.ath.cx", "connect"));
    
      loadit();
    }
    
    void loadit() {
      loader = new Thread(new DynamicLoader(this));
      loader.start();
    }
    
    void saveit() {
      saver = new Thread(new DynamicSaver(this));
      saver.start();
    }
    
    
    void draw() {
      
      if(!loaded){
       background(255);
       textAlign(CENTER);
       String dots = "";
       for(int i =0;i<(sin(frameCount/20.0)+1)*30;i++)
       dots+=".";
       fill(0);
       text("loading an image from server",width/2,height/2);
       text(dots,width/2,height/2+8);
       pushMatrix();
       
       popMatrix(); 
        
      }else{
    
    
      brush.update();
    
      if (paint)
        brush.paint();
    
      if (saved) {
        displaySaved();
      }
    
    
    
      brush.postUpdate();
      }
    }
    
    void mousePressed() {
      if (mouseButton!=LEFT) {
        brush.changeColor();
      }
      else {
    
        if (saved) {
          saved = false;
        }
        erase();
        paint = true;
      }
    }
    
    
    void mouseReleased() {
      paint = false;
    
      //fastblur(g,1);
    }
    
    void keyPressed() {
      saveit();
    }
    
    
    void display() {
    
    
      fill(0);
      noStroke();
      rect(0, height-10, width, 10);
      fill(255, 128, 0);
    
      textAlign(LEFT);
      text("Collaborative Painting @ openprocessing.org", 10, height-2);
    
      textAlign(RIGHT);
      text("timestamp: "+
        year()+" "+
        nf(day(), 2)+"/"+
        nf(month(), 2)+" @ "+
        nf(hour(), 2)+":"+
        nf(minute(), 2)+":"+
        nf(second(), 2), 
      width-10, height-2);
    }
    
    void displaySaved() {
    
      fill(0);
      noStroke();
      rect(0, height-10, width, 10);
      fill(255, 128, 0);
    
      textAlign(CENTER);
      text("*** SAVED ***", width/2, height-2);
    }
    
    void erase(){
      
      fill(0);
      noStroke();
      rect(0, height-10, width, 10);
      
      fill(255, 128, 0);
    
      textAlign(CENTER);
      text("*** PRESS ANY KEY TO SAVE ***", width/2, height-2);
    }
    
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Kryštof Pešek (Kof)

    Collab Painting

    Add to Faves Me Likey@! 1
    You must login/register to add this sketch to your favorites.

    Little experiment with an ability to save image outside the server ..saving to my home server >> http socket + little php script.


    *Please accept certificate

    LEFT MOUSE drag to paint

    RIGHT MOUSE click to change color

    PRESS ANY KEY TO SAVE AND DOWNLOAD

    collection is growing here:

    http://lab19.dyndns.org/gallery.php

    ale
    18 Mar 2012
    Nice research... thx for sharing!
    ^-^
    Thanks Ale, You're welcomed

    ..I am still thinking about other possibilities.. I think there are much more.
    This is amazing! Do I get it right, that it saves anyone's drawings and serves a combined image next time someone visits?
    Yes, that's it. It creates persisting images.. the php script is retrieving a last modified file on my server. This image is loaded into applet, and after new paint it can upload a PNG image via modified piece of Seltar's library *Post To Web*. (png option had been broken)

    http://libraries.seltar.org/postToWeb/
    Brendan Flynn
    26 Jun 2012
    thats awesome dude, im sure you know of all aaron koblins work, that and electric sheep pop to mind beautiful thing you have done here sharing.
    Brendan Flynn
    26 Jun 2012
    taking very long time to get going for my crap, band width. will try again later when not so tired.
    Band-width is also very low on my side, it is really punk lo-fidelity server I am sitting next to, it needs a bit o patience, so thanks for collaborating.. nice painting, I hope you got the "Souvenir" back ))
    Jean Gilbert
    29 Jan 2014
    so nice colours, just a great work for itself, but you top it with a collab, that's tremendous!
    You need to login/register to comment.