Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Forums Adobe After Effects Expressions how can i center the anchor point based on opacity of a comp’s contents?

  • how can i center the anchor point based on opacity of a comp’s contents?

  • Seth Olson

    December 21, 2022 at 11:16 pm

    i have a comp with transparency. i want to center the anchor point of the comp to the area of opacity. I tried this on the comp:

    // [CENTER, CENTER]
    l = thisLayer.sourceRectAtTime();
    [l.left + l.width/2, l.top + l.height/2];

    but it seems to measure the entire comp, not the opaque areas. Suggestions?

  • Dan Ebberts

    December 21, 2022 at 11:26 pm

    The only thing I can think of is the old brute-force sampleImage() method:

    h = height/2;
    w = width/2;
    for (i = 0; i < width; i++){
    if (sampleImage([i,h],[.5,h])[3]>0) break;
    }
    left = i;
    for (i = width-1; i >= 0; i--){
    if (sampleImage([i,h],[.5,h])[3]>0) break;
    }
    right = i;
    for (i = 0; i < height; i++){
    if (sampleImage([w,i],[w,.5])[3]>0) break;
    }
    top = i;
    for (i = height-1; i >= 0; i--){
    if (sampleImage([w,i],[w,.5])[3]>0) break;
    }
    bottom = i;
    [(left+right)/2,(top+bottom)/2]
  • Dan Ebberts

    December 22, 2022 at 7:06 pm

    I think this is actually a little (half a pixel) more precise:

    h = height/2;
    w = width/2;
    for (i = 0.5; i < width; i++){
    if (sampleImage([i,h],[.5,h])[3]>0) break;
    }
    left = i;
    for (i = width-0.5; i > 0; i--){
    if (sampleImage([i,h],[.5,h])[3]>0) break;
    }
    right = i;
    for (i = 0.5; i < height; i++){
    if (sampleImage([w,i],[w,.5])[3]>0) break;
    }
    top = i;
    for (i = height-0.5; i > 0; i--){
    if (sampleImage([w,i],[w,.5])[3]>0) break;
    }
    bottom = i;
    [(left+right)/2,(top+bottom)/2]
  • Seth Olson

    December 22, 2022 at 8:06 pm

    Ok, this works very well, but also very slowly. It requires several seconds to process each frame.

    Is there a way to get the property using sourceRectAtTime() on the first layer inside the comp?

    something like: sc=comp(“1”).layer(0).sourceRectAtTime();

    but then I get an error that “index 0 is out of range”

    maybe something made up like: thisLayer.firstLayer.sourceRectAtTime();

    Thank you for your help!

  • Dan Ebberts

    December 22, 2022 at 9:53 pm

    sourceRectAtTime() won’t detect the zero-alpha areas of precomp layers.

    You could always convert the anchor point expression to keyframes. That might help.

  • Filip Vandueren

    January 12, 2023 at 10:20 am

    Here’s a version that uses binary search so is exponentially faster:

    Note that it works best in 16 or 32 bpc for images that have a very small amount of opaque pixels ( < 0,4%)

    // posterizeTime(0); // uncomment for still images
    includeEffects = false;
    l=thisLayer;
    w=l.source.width;
    h=l.source.height;
    threshold = 0;
    width_bits = Math.ceil(Math.log(w)/Math.log(2));
    height_bits = Math.ceil(Math.log(h)/Math.log(2));
    left = 0; right = 0;
    for (b=width_bits-1; b>=0; b--) {
    slice_width = 2**b;
    if (l.sampleImage([left + slice_width/2, h/2], [slice_width/2, h/2],includeEffects)[3]<=threshold) {
    left+=slice_width;
    }
    if (l.sampleImage([w - (right + slice_width/2), h/2], [slice_width/2, h/2],includeEffects)[3]<=threshold) {
    right+=slice_width;
    }
    }
    right= w-right;
    top = 0; bottom = 0;
    for (b=height_bits-1; b>=0; b--) {
    slice_height = 2**b;
    if (l.sampleImage([w/2, top + slice_height/2], [w/2, slice_height/2],includeEffects)[3]<=threshold) {
    top+=slice_height;
    }
    if (l.sampleImage([w/2, h - (bottom + slice_height/2)], [w/2, slice_height/2],includeEffects)[3]<=threshold) {
    bottom+=slice_height;
    }
    }
    bottom = h-bottom;
    [left+right, top+bottom]/2
Viewing 1 - 6 of 6 posts

Log in to reply.

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