# How to save frames with many transparent images?

**URL:** <https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522>\
**Category:** Coding Questions\
**Created:** [June 6, 2021, 7:17am UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522 "2021-06-06T07:17:02Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![noodleSystem](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlesystem/32/13535_2.png) [@noodleSystem](https://discourse.processing.org/u/noodleSystem)\
**Post date:** [June 6, 2021, 7:17am UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/1 "2021-06-06T07:17:02Z")

</div>

This is kind of a weird question, please forgive the longwinded explanation:

There must be an easier way to do this. I’m trying to save each frame (as it appears on the screen) and make a movie, but the frame captures that processing saves don’t look like the window, and I think because I added transparency to each pixel!

This code is just a super basic, modified Open Simplex Noise example. Since a new noise layer is added on top of the previous one, each frame I save needs to contain all the previous frames as layers as well (I think). This is all because save() and saveFrame() don’t capture what the screen actually looks like!

I created an array of PImage objects to store the images, but I’m not sure how to save them on top of each other?

If that approach is not possible then I was thinking I might have to iterate over every pixel from every previous frame and layer them all on top of each other? I feel like I must be missing something though…

Any advice or input would be greatly appreciated!

```auto
// https://thecodingtrain.com/CodingChallenges/137-4d-opensimplex-noise-loop

int totalFrames = 360;
int counter = 0;
boolean record = true;
boolean fourD = false;
PImage[] layeredImages = new PImage[360];

PImage img;

//zoom
float increment = 0.03;

// Just for non-looping demo
float zoff = 0;

OpenSimplexNoise noise;
void setup() {
  size(640, 360);
  img = createImage(640, 360, ARGB);
  noise = new OpenSimplexNoise();
}

void draw() {
  
  float percent = 0;
  if (record) {
    percent = float(counter) / totalFrames;
  } else {
    percent = float(counter % totalFrames) / totalFrames;
  }
 
  render(percent, counter);
    
  if (record) {
    layeredImages[counter] = img;
    layeredImages[counter].save("img/"+nf(counter, 3)+".png");
    if (counter == totalFrames-1) {
      exit();
    }
  }
  counter++;
}

void render(float percent, int counter) {
  float angle = map(percent, 0, 1, 0, TWO_PI);
  float uoff = map(sin(angle), -1, 1, 0, 2);
  float voff = map(sin(angle), -1, 1, 0, 2);
  float xoff = 0;
  
  img.loadPixels();
  for (int x = 0; x < width; x++) {
    float yoff = 0;
    for (int y = 0; y < height; y++) {
      float n;
      if (fourD) {
        // 4D Open Simplex Noise is very slow!
        n = (float) noise.eval(xoff, yoff, uoff, voff)*255+100;
      } else {
        // If you aren't worried about looping run this instead for speed!
        n = (float) noise.eval(xoff, yoff, zoff)*255+100;
      }
      //float bright = n > 0 ? 255 : 0;
      img.pixels[x + y * width] = color(n, n, n, 3);
      yoff += increment;
    }
    xoff += increment;
  }

  img.updatePixels();
  image(img, 0, 0);
  
  zoff += increment;
}

```

---

<div class="post-metadata">

**Author:** ![JSGauthier](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jsgauthier/32/9910_2.png) [@JSGauthier](https://discourse.processing.org/u/JSGauthier)\
**Post date:** [June 7, 2021, 4:31pm UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/2 "2021-06-07T16:31:17Z")

</div>

Hello,

Perhaps you can write each PImage layer to a PGraphics() object?  
createGraphics() will allow you to write to a seperate buffer.  
You can write multiple frames onto each other (keeping their transparency using beginDraw() and endDraw() to composite your layers. Then display them using image().

https://processing.org/reference/PGraphics.html  
https://processing.org/reference/createGraphics\_.html  
https://processing.org/reference/PGraphics\_beginDraw\_.html

---

<div class="post-metadata">

**Author:** ![noodleSystem](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlesystem/32/13535_2.png) [@noodleSystem](https://discourse.processing.org/u/noodleSystem)\
**Post date:** [June 9, 2021, 6:09am UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/3 "2021-06-09T06:09:56Z")

</div>

Thanks for the reply!

I looked thru the docs a ton and managed to _almost_ make it work but I am missing something crucial. It seems that the first image is being assigned to every array index. So my graphics screenshots are layered with the right number of transparent layers (yay transparency!) but they are all the same image. ☹

My print statements show that each array index is being assigned properly by the for loop. There must be some hole in my understanding of the _pixels \> image \> image array \> graphics_ pipeline that i can’t seem to crack.

Here’s a more simplified version of the code above but with my progress from your suggestion.

```auto
int totalFrames = 360;
int counter = 0;
PImage[] layerArray = new PImage[totalFrames];

PImage layer;
PGraphics screenShot;

//Some Noise Settings
float increment = 0.03;
float zoff = 0;

OpenSimplexNoise noise;

void setup() {
  size(640, 360);
  layer = createImage(640, 360, ARGB);
  screenShot = createGraphics(640, 360);
  noise = new OpenSimplexNoise();
}

void draw() {
  //function that draws the noise pixels and creates an image
  render(counter);
  
  //assign the image to the array
  layerArray[counter] = layer;

  //start drawing the graphics object
  screenShot.beginDraw();

  //assign all previously drawn images to the graphics object
  for (int i = 0; i < counter+1; i++){
    screenShot.image(layerArray[i], 0, 0);
    print("layerArray["+i+"] drawn to buffer\n");
  }
  screenShot.endDraw();
  screenShot.save("img/"+nf(counter, 3)+".png");
  print("screenShot "+counter+" saved\n\n");
  counter++;
}

//Drawing the noise pixels
void render(int counter) {
  float angle = map(0, 0, 1, 0, TWO_PI);
  float uoff = map(sin(angle), -1, 1, 0, 2);
  float voff = map(sin(angle), -1, 1, 0, 2);
  float xoff = 0;
  
  layer.loadPixels();
  for (int x = 0; x < width; x++) {
    float yoff = 0;
    for (int y = 0; y < height; y++) {
      float n;
      n = (float) noise.eval(xoff, yoff, zoff)*255+100;
      layer.pixels[x + y * width] = color(n, n, n, 3);
      yoff += increment;
    }
    xoff += increment;
  }
  
  layer.updatePixels();
  image(layer, 0, 0);
  zoff += increment;
}

```

---

<div class="post-metadata">

**Author:** ![JSGauthier](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jsgauthier/32/9910_2.png) [@JSGauthier](https://discourse.processing.org/u/JSGauthier)\
**Post date:** [June 9, 2021, 4:12pm UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/4 "2021-06-09T16:12:51Z")

</div>

Hello,

You may only need to set the P2D renderer for the composition and the graphics buffer to P2D.

size(640, 360, P2D) ;  
screenShot = createGraphics(640, 360, P2D);

I noticed this has a different behaviour when I tried it but the output frames were all identical.

I applied screenshot.clear() to remove previous pixeldata in the PGraphics layer and the output frames are now different. Is that the result you sought?

link to clear() in the reference: [clear() \ Language (API) \ Processing 3+](https://processing.org/reference/clear_.html)

I wonder if you can simply skip the PImage[] altogether and simply apply the noise directly to your PGraphics layer (which can be made into an array if you wish) and then write the PGraphics to image()?

Cheers,  
JSG

```auto
int totalFrames = 360;

int counter = 0;

PImage[] layerArray = new PImage[totalFrames];

PImage layer;

PGraphics screenShot;

//Some Noise Settings

float increment = 0.03;

float zoff = 0;

OpenSimplexNoise noise;

void setup() {

  size(640, 360, P2D);

  layer = createImage(640, 360, ARGB);  

  screenShot = createGraphics(640, 360, P2D);

  noise = new OpenSimplexNoise();

}

void draw() {

  //function that draws the noise pixels and creates an image

  render(counter);

  

  //assign the image to the array

  layerArray[counter] = layer;

  //start drawing the graphics object

  screenShot.beginDraw();
  screenShot.clear();
  //assign all previously drawn images to the graphics object
  for (int i = 0; i < counter+1; i++){
  
    screenShot.image(layerArray[i], 0, 0);
    print("layerArray["+i+"] drawn to buffer\n");
  }

  screenShot.endDraw();

  screenShot.save("img/"+nf(counter, 3)+".png");
  print("screenShot "+counter+" saved\n\n");
  counter++;

}

//Drawing the noise pixels

void render(int counter) {

  float angle = map(0, 0, 1, 0, TWO_PI);

  float uoff = map(sin(angle), -1, 1, 0, 2);

  float voff = map(sin(angle), -1, 1, 0, 2);

  float xoff = 0;

  layer.loadPixels();

  for (int x = 0; x < width; x++) {

    float yoff = 0;

    for (int y = 0; y < height; y++) {

      float n;

      n = (float) noise.eval(xoff, yoff, zoff)*255+100;

      layer.pixels[x + y * width] = color(n, n, n, 3);

      yoff += increment;

    }

    xoff += increment;

  }

  

  layer.updatePixels();

  image(layer, 0, 0);

  zoff += increment;

}

```

---

<div class="post-metadata">

**Author:** ![noodleSystem](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlesystem/32/13535_2.png) [@noodleSystem](https://discourse.processing.org/u/noodleSystem)\
**Post date:** [June 10, 2021, 7:23am UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/5 "2021-06-10T07:23:06Z")

</div>

That worked!

But dang the P2D renderer looks suuper different from the default renderer. This is rather unfortunate. I wonder if there is a way to make it look smoother and less stepped like the default. Looking thru some posts and the docs, it seems like messing with the P2D render settings might be challenging… 🤔

 ![Default_VS_P2D_bw](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/f/f3208b7ab7445756d751e3df4110835388a8424e.png)

---

<div class="post-metadata">

**Author:** ![JSGauthier](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jsgauthier/32/9910_2.png) [@JSGauthier](https://discourse.processing.org/u/JSGauthier)\
**Post date:** [June 10, 2021, 2:33pm UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/6 "2021-06-10T14:33:18Z")

</div>

I’m glad I coudl help! I had many of the same issues with some of my projects.

P2D and P3D do look a bit different but you can use smooth() to reduce aliasing.

[https://processing.org/reference/smooth\_.html](https://processing.org/reference/smooth_.html)

Way to perservere my friend!

Best,  
JS

---

<div class="post-metadata">

**Author:** ![noodleSystem](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlesystem/32/13535_2.png) [@noodleSystem](https://discourse.processing.org/u/noodleSystem)\
**Post date:** [June 11, 2021, 5:43am UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/7 "2021-06-11T05:43:25Z")

</div>

I’ll mess with that. Thanks for the help!  
-Mark

---

<div class="post-metadata">

**Author:** ![JSGauthier](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jsgauthier/32/9910_2.png) [@JSGauthier](https://discourse.processing.org/u/JSGauthier)\
**Post date:** [June 15, 2021, 7:20pm UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/8 "2021-06-15T19:20:32Z")

</div>

All you really need to add is

smooth(8); //the higher the # the smoother the antialising.

to the line after size() in your setup() loop.

Take care.  
js

---

<div class="post-metadata">

**Author:** ![noodleSystem](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlesystem/32/13535_2.png) [@noodleSystem](https://discourse.processing.org/u/noodleSystem)\
**Post date:** [June 16, 2021, 4:36am UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/9 "2021-06-16T04:36:42Z")

</div>

Unfortunately smooth(8); had no effect on the banding. It looks the same with it on. 🙁

---

<div class="post-metadata">

**Author:** ![JSGauthier](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jsgauthier/32/9910_2.png) [@JSGauthier](https://discourse.processing.org/u/JSGauthier)\
**Post date:** [June 16, 2021, 1:58pm UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/10 "2021-06-16T13:58:52Z")

</div>

Bummer. Perhaps hint() a related setting can help change the rendering settings.  
[https://processing.org/reference/hint\_.html](https://processing.org/reference/hint_.html)

Best of luck.  
-JS

---

<div class="post-metadata">

**Author:** ![noodleSystem](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noodlesystem/32/13535_2.png) [@noodleSystem](https://discourse.processing.org/u/noodleSystem)\
**Post date:** [August 13, 2021, 7:45pm UTC](https://discourse.processing.org/t/how-to-save-frames-with-many-transparent-images/30522/11 "2021-08-13T19:45:35Z")

</div>

Does anyone know of maybe a high quality screen recorder I can use to work around this issue? When I use the native mac screen recorder, there is a bit of banding/discoloration in the gradients.

The sketch only looks smooth/perfect (on my screen) and with the default renderer, but I can’t save those frames in a buffer bc they have transparency. The P2D renderer does have transparency but the banding on it is horrific and unfortunately hint() and smooth() did not solve the issue.

It’s not as noticeable in the still but when it’s moving the banding is hecking distracting ☹

 ![Screen Shot 2021-08-13 at 2.44.45 PM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/1/11a390c90d50e77e0a07de36513cec69bdad2b99.jpeg)
