Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Expressions Need to Analyze Pixel Differences between frames to Trigger Expression

  • Need to Analyze Pixel Differences between frames to Trigger Expression

    Posted by Jonathan Moxness on October 21, 2022 at 6:16 pm

    I’m trying to create an expression that can compare one frame of an animation layer with the next frame to determine if there is any difference between the two and if so, trigger a texture overlay precomp to cycle to the next texture (if not it stays static).

    Sometimes the animation is on twos but sometimes it switches to ones, and sometimes it’s just static because the character is just supposed to be static. The outcome I’m trying to achieve is having some texture overlays that change every time the animation changes without having to manually keyframe everything.

    I know that you can use the Difference Matte effect to analyze two frames and only display the differences, which is great if I just duplicate the layer and offset by one frame. What I’d love to know is if I can easily analyze each frame to do something like return a “TRUE” value if there is any pixel data within the frame, and return a “FALSE” value if there is no pixel data within the frame. If I can get help with either achieving this or being told it’s not possible, that’d be a great first step!

    Thanks in advance!

    Jonathan Moxness replied 3 years, 6 months ago 2 Members · 5 Replies
  • 5 Replies
  • Dan Ebberts

    October 21, 2022 at 7:05 pm

    I don’t know how practical it is (because it uses sampleImage(), which can bring your system to its knees), but this should start a counter (which you could use to drive a triggered action) whenever it detects something in your Difference Matte layer:

    L = thisComp.layer("Difference Matte Layer");
    tRun = 0;
    s = L.sampleImage([L.width,L.height]/2,[L.width,L.height]/2);
    trig = (s[0]+s[1]+s[2]) > 0;
    t = time - thisComp.frameDuration;
    while (t >= 0){
    s = L.sampleImage([L.width,L.height]/2,[L.width,L.height]/2,true,t);
    if (trig){
    if (s[0]+s[1]+s[2] == 0){
    tRun = time - t;
    break;
    }
    }else{
    trig = (s[0]+s[1]+s[2]) > 0;
    }
    t -= thisComp.frameDuration;
    }
    tRun
  • Jonathan Moxness

    October 21, 2022 at 7:33 pm

    If I put this script into a slider or the source text of a layer, it does change values when it detects changes in the difference matte, but it doesn’t seem to be counting up. Most of the time it switches from a value of 0.041666666667 if there is data in the frame to a value of 0.08333333333333 if there is no pixel data in the frame (but sometimes this is not the case).

    Not sure if I’m using it correctly though. Dan what property/layer would you put this expression on to have it count up every time it detects a difference in the matte layer?

    Thanks Dan!

  • Jonathan Moxness

    October 21, 2022 at 8:32 pm

    So what it seems to be doing is that it will count up the consecutive blank frames, but as soon as a new frame containing some different pixels appears, the counter resets to 0.04166666666. Since most of the animation is on twos this is why it goes from 0.0416666666 to .08333333, then resets back to 0.0416666666 on the next new frame. When the character holds a pose for multiple frames though, the counter ticks up each frame until reseting again when the pose changes.

    What I’m trying to do is instead of the counter ticking up on consecutive frames where the image remains static (and then reseting on a new pose), the counter would remain static so long as the pose is static, and ticks up only when the pose changes (ie. the difference matte displays new information).

  • Dan Ebberts

    October 21, 2022 at 8:46 pm

    I think that would actually be a little simpler (if I’m understanding what you’re describing), like this:

    L = thisComp.layer("Difference Matte Layer");
    count = 0;
    f = timeToFrames(time);
    for (i = 0; i <= f; i++){
    s = L.sampleImage([L.width,L.height]/2,[L.width,L.height]/2,true,framesToTime(i));
    if ((s[0]+s[1]+s[2]) > 0) count++;
    }
    count
  • Jonathan Moxness

    October 21, 2022 at 8:51 pm

    🤩 This works perfectly! Thanks so much Dan! You are amazing!!!! 🙏

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy