0

Clarifying my last question:

I would like to display, in Processing, many photos fading up and fading down over 15 seconds, with one second between their start times, so there are about 15 images on the screen at a time, at various levels of fading.

This example displays 15 objects, but they all start together:

PImage[] imgs = new PImage[42];
Pic[] pics = new Pic[15];

void setup() {
  size(1000, 880);
  for (int i = 0; i < pics.length; i++) {
  pics[i] = new Pic(int(random(0, 29)), random(0, 800), random(0, height));
  }
  for (int i = 0; i < imgs.length; i++) {
    imgs[i] = loadImage(i+".png");
  }
}

void draw() {
  background(255);
  for (int i = 0; i < pics.length; i++) {
    pics[i].display();
  }
}

class Pic {
  float x;
  float y;
  int num;
  int f = 0;
  boolean change = true;

  Pic(int tempNum, float tempX, float tempY) {
    num = tempNum;
    x = tempX;
    y = tempY;
  }

  void display() {
    imageMode(CENTER);
    if (change)f++;
    else f--;
    if (f==0||f==555)change=!change;
    tint(0, 153, 204, f);
    image(imgs[num], x, y);
  }
}
Ouroborus
  • 16,237
  • 4
  • 39
  • 62
user2449986
  • 77
  • 1
  • 10

1 Answers1

0

If you can fade an image, then you can also cross fade an image by subtracting the fade amount from the maximum fade value (e.g. inverting the fade value).

In your case you're using tint so it's a value from 0-255. Let's say tint is your variable: 255 - tint would be the inverted value.

Here's a basic sketch you can run that illustrates this (using fill() instead of tint()):

void draw(){
  
  float fade = map(sin(frameCount * 0.03), -1.0, 1.0, 0, 255);
  
  background(0);
  noStroke();
  // use fade value
  fill(192, 0, 192, fade);
  ellipse(45, 50, 60, 60);
  // invert the fade value (by subtracting it from the max value)
  fill(0, 192, 192, 255 - fade);
  ellipse(60, 50, 60, 60);
  
}

Continuing from the previous question and answer you can tweak the code to use an inverted tint value to crossfade. The catch is you'd need to store a reference to the previous image to apply the inverted tint to:

PImage[] imgs = new PImage[42];
ImagesFader fader;

void setup(){
  size(255, 255);
  frameRate(60);
  // load images
  for (int i = 0; i < imgs.length; i++) {
    imgs[i] = loadImage(i+".png");
  }
  // setup fader instance
  // constructor args: PImage[] images, float transitionDurationSeconds, int frameRate
  // use imgs as the images array, transition in and out within 1s per image at 60 frames per second 
  fader = new ImagesFader(imgs, 3.0, 60);
}

void draw(){
  background(0);
  fader.draw();
}

class ImagesFader{
  
  int numFrames;
  int numFramesHalf;
  
  int frameIndex = 0;
  
  PImage[] images;
  int maxImages  = 15;
  
  int randomImageIndex;
  float randomX, randomY;
  
  PImage previousImage;
  float previousX, previousY;

  ImagesFader(PImage[] images, float transitionDurationSeconds, int frameRate){
    numFrames = (int)(frameRate * transitionDurationSeconds);  
    numFramesHalf = numFrames / 2;
    println(numFrames);
    this.images = images;
    // safety check: ensure maxImage index isn't larger than the total number of images
    maxImages = min(maxImages, images.length - 1);
    // pick random index
    randomizeImage();
  }
  
  void draw(){
    updateFrameAndImageIndices();
    PImage randomImage = imgs[randomImageIndex];
    
    // isolate drawing style (so only the image fades, not everything in the sketch)
    pushStyle();
    // if there is a previous image, cross fade it
    float tintAlpha = tintFromFrameIndex();
    if(previousImage != null){
      // invert tint -> max(255) - value
      tint(255, 255 - tintAlpha);
      image(previousImage, previousX, previousY);
    }
    // render current random image (on top of the previous one, if any)
    tint(255, tintAlpha);
    image(randomImage, randomX, randomY);
    
    popStyle();
  }
  
  float tintFromFrameIndex(){
    int frameIndexToTint = abs(frameIndex - numFramesHalf);
    return map(frameIndexToTint, 0, numFramesHalf, 255, 0);
  }
  
  void updateFrameAndImageIndices(){
    // increment frame
    frameIndex++;
    // reset frame (if larger than transition frames total)
    if(frameIndex >= numFrames){
      // update previous image before generating another random image
      previousImage = imgs[randomImageIndex];
      previousY = randomX;
      previousY = randomY;
      
      frameIndex = 0;
      // randomize index and position
      randomizeImage();
      println("fade transition complete, next image: ", randomImageIndex);
    }
  }
  
  void randomizeImage(){
    randomImageIndex = int(random(0, 29));
    randomX = random(width);
    randomY = random(height);
  }
  
}

The above skeetch might not be 100% accurate (as I don't fully get the randomisation logic), but hopefully it illustrates the mechanism of crossfading.

George Profenza
  • 50,687
  • 19
  • 144
  • 218