Saving sketch with a transparent background

edited August 2015 in Questions about Code

Hey,

I'm looking for some help with a simple way of saving the frame of a sketch as a png with no background, other than the drawn lines from the script. The sketch essentially reproduces a given image through a series of generated traceur lines, I've included the sketch for reference and it's something I found so I don't fully understand how it works. I'm new to processing so I apologize if this is really basic or if I'm missing something but after looking around, it seems surprisingly more complicated than I initially thought to render with no background. I'm using the latest version of processing 3 by the way.

PGraphics alphaG;

PImage g;
traceur[] traceurs;

void setup(){
size(2500,800);


   alphaG = createGraphics(width,height, JAVA2D);

  g = loadImage("climate.png");

  traceurs = new traceur[0];
  background(255);
  stroke(126,24,175,20);
  for(int a=0;a<120;a++){
    traceurs = (traceur[]) append (traceurs, new traceur());
  }

}

void draw(){
  for(int a=0;a<traceurs.length;a++){
   traceurs[a].dessine(); 
  } 

 image(alphaG, 0,0);
}

class traceur{
    float x,y,an,v;
    float[] rang={-0.05,0.05};
  traceur(){
    x= random(width);y=random(height);
    an=random(TWO_PI);v=random(1.2,1.5);
   rang[0]=random(-0.1,-0.05);
   rang[1]=random(0.05, 0.1);
  }
  void dessine(){
   an+=random(rang[0],rang[1]);
   float newx=x+cos(an)*v;
   float newy=y+sin(an)*v;
   if(newx<0||newx>width||newy<0||newy>height){
     newx=constrain(newx,0,width);
     newy=constrain(newy,0,height);
     an+=random(-PI,PI);
   rang[0]=random(-0.1,-0.05);
   rang[1]=random(0.05, 0.1);
   }
   if(random(100)<1){ 
   rang[0]=random(-0.1,-0.05);
   rang[1]=random(0.05, 0.1);
   }
   float angleChoisi=an;

   float couleur=brightness(g.get(int(newx),int(newy)));
   for(float a=an-PI*0.3;a<an+PI*0.3;a+=PI*0.15){
      int ixe=int(newx+cos(a)*v);
      int igr=int(newy+sin(a)*v);
      float col=brightness(g.get(ixe,igr));
      if(col<couleur){
        couleur=col;
        angleChoisi=a;
      }
   } 
   an=angleChoisi;
   if(random(100)<1){an=an+random(-1,1);}
   line(x,y,newx,newy);
   x=newx;y=newy;

}
  }


 void keyReleased(){
  saveFrame("img#####.png");
}

I found another code which I tried incorporating that is pretty helpful in rendering with no background, with some pretty clear instructions for beginners, it utilizes pgraphics to render, but since I don't fully understand how the initial code works, I've been having a hard time incorporating the various drawing steps. I've included the original file here for reference.

PGraphics alphaG;

void setup() {
size(1250,800); 
// create an extra pgraphics object for rendering on a transparent background 
 alphaG = createGraphics(width,height, JAVA2D);

// background will be transparent in the png-file 
background(255);
}

void draw() {

  // draw into the pgraphics object
  alphaG.beginDraw();
    alphaG.fill(255,100);
    alphaG.rect(random(width), random(height), 30,30); 
  alphaG.endDraw();

  // draw the second renderer into the window, so we can see something 
  image(alphaG, 0,0);
}

void keyPressed() {
   alphaG.save("alphatest.png"); 
   println("alphatest.png saved.");
}

Anyways, I hope what I'm asking makes some sense, and I would really appreciate anyone's help on this, thanks.

Best,
David

Answers

  • edited August 2015

    Here's some option. Use get() to clone canvas as a PImage.
    Change its format to ARGB as well.
    Then check each color from its pixels[]. If it's the same as background()'s, make it transparent.
    Finally save() it w/ name based on current frameCount: :ar!

    // forum.processing.org/two/discussion/12036/
    // saving-sketch-with-a-transparent-background
    
    // by GoToLoop (2015-Aug-11)
    
    static final color BG = -1, STROKE = 0;
    static final float FPS = 2, OUTLINE = 2.5;
    
    void setup() {
      size(320, 260, JAVA2D);
      smooth(4);
      frameRate(FPS);
    
      ellipseMode(CENTER);
      strokeWeight(OUTLINE);
      stroke(STROKE);
    }
    
    void draw() {
      background(BG);
      fill((color) random(#000000));
      ellipse(width>>1, height>>1, width>>1, height>>1);
    }
    
    void mousePressed() {
      // Pass same color used for background():
      saveTransparentCanvas(BG, "img");
    }
    
    void saveTransparentCanvas(final color bg, final String name) {
      final PImage canvas = get();
      canvas.format = ARGB;
    
      final color p[] = canvas.pixels, bgt = bg & ~#000000;
      for (int i = 0; i != p.length; ++i)  if (p[i] == bg)  p[i] = bgt;
    
      canvas.updatePixels();
      canvas.save(dataPath(name + nf(frameCount, 4) + ".png"));
    }
    
  • GoToLoop,

    Thanks for the response, I tried incorporating the code you provided while swapping a few things to include the draw code I shared earlier and though it's running ok, I'm not getting the drawn linework, just a blank png. I've included the adapted code to reference.

    I think I'm just having a hard time understanding how the original code draws in the first place and I realize it's not the best trying to break down this sketch that I found but I'll keep working on it. Otherwise, if I missed something or have something really dumb in the code, I apologize, I'm super new to all of this and I'd really appreciate another look if you've got the time. Thanks again

    static final color BG = -1, STROKE = 0;
    static final float FPS = 2, OUTLINE = 2.5;
    
    PImage g;
    traceur[] traceurs;
    
    void setup(){
    size(2500,800, JAVA2D);
    
    smooth(4); 
    
      g = loadImage("climate.png");
    
      traceurs = new traceur[0];
      background(255);
      stroke(126,24,75,20);
      for(int a=0;a<120;a++){
        traceurs = (traceur[]) append (traceurs, new traceur());
      }
    
    }
    
    void draw(){
        background(BG);
      fill((color) random(#000000));
      for(int a=0;a<traceurs.length;a++){
       traceurs[a].dessine(); 
      } 
    
    
    }
    
    class traceur{
        float x,y,an,v;
        float[] rang={-0.05,0.05};
      traceur(){
        x= random(width);y=random(height);
        an=random(TWO_PI);v=random(1.2,1.5);
       rang[0]=random(-0.1,-0.05);
       rang[1]=random(0.05, 0.1);
      }
      void dessine(){
       an+=random(rang[0],rang[1]);
       float newx=x+cos(an)*v;
       float newy=y+sin(an)*v;
       if(newx<0||newx>width||newy<0||newy>height){
         newx=constrain(newx,0,width);
         newy=constrain(newy,0,height);
         an+=random(-PI,PI);
       rang[0]=random(-0.1,-0.05);
       rang[1]=random(0.05, 0.1);
       }
       if(random(100)<1){ 
       rang[0]=random(-0.1,-0.05);
       rang[1]=random(0.05, 0.1);
       }
       float angleChoisi=an;
    
       float couleur=brightness(g.get(int(newx),int(newy)));
       for(float a=an-PI*0.3;a<an+PI*0.3;a+=PI*0.15){
          int ixe=int(newx+cos(a)*v);
          int igr=int(newy+sin(a)*v);
          float col=brightness(g.get(ixe,igr));
          if(col<couleur){
            couleur=col;
            angleChoisi=a;
          }
       } 
       an=angleChoisi;
       if(random(100)<1){an=an+random(-1,1);}
       line(x,y,newx,newy);
       x=newx;y=newy;
    
    }
      }
    
    
    void mousePressed() {
      // Pass same color used for background():
      saveTransparentCanvas(BG, "img");
    }
    
    void saveTransparentCanvas(final color bg, final String name) {
      final PImage canvas = get();
      canvas.format = ARGB;
    
      final color p[] = canvas.pixels, bgt = bg & ~#000000;
      for (int i = 0; i != p.length; ++i)  if (p[i] == bg)  p[i] = bgt;
    
      canvas.updatePixels();
      canvas.save(dataPath(name + nf(frameCount, 4) + ".png"));
    }
    
  • GoToLoop,

    Thanks for the solution to this.

    Do you have any advice for getting around the problem of having no stroke or the stroke set to the same color as the background?

    The following image is an example where the stroke is set to the same color as the background (background set to black to make the outline more visible): https://dl.dropboxusercontent.com/u/83925/transparentBackground.png

    There's a glitchiness to it that I'm looking to avoid.

    Thanks for any help!

Sign In or Register to comment.