• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Get the x position for underlaying layer is white

Participant ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

Hey! 

 

Trying to figure out how to do this but I'm not as good with code as I want... 

 

The concept is:

• I have a layer from which I want to sample to color information using sampleImage

• On a each layer I want a for loop stepping through the x position one pixel at the tame until the sampled color is white

• When the desired color is found I want the for loop to stop executing. 

• Next step is I want to measure the distance from the left side of the comp until this new x position of the color change.

 

I figured this concept is not that complicated but my for loops keeps crashing. 

 

Anyone have an idea how to set this up? 

 

 

 

 

TOPICS
Expressions , How to , Scripting

Views

806

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

If you already have code, you need to include it in your post. If it crashes your loops probably don't terminate and you run out of memory. Otherwise it shouldn't be too difficult to construct something with two simple nested for() loops to comb through the lines and then through the X positions and you simply add break and continue rules to the loops.

 

Mylenium

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

It only needs to do one line, meaning the current y position of the layer. Not going down. 

 

 

 

 

x = 0;
found = false;
while (!found && x <= thisComp.width) {
    sampleColor = thisComp.layer("sample").sampleImage([x, transform.yPosition], [1, 1]);
    if (sampleColor[0] == 1) {
        found = true;
    } else {
        x += 1;
    }
}
if (found) {
    x;
} else {
    value;
}

 

 

 

This is the code I'm trying with but it's a mess. Not a coder.  

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

I've just tried your code and I think the problem is that (asuming HD) you're asking it to perform up to 1920 sampleImage calculations.  And due to the way After Effects works, it then performs all the same again on the next frame as expressions have no "frame memory".  

What's the purpose for this expression?  Maybe there's a better way to get the end result.

 

This is a slightly smaller version of your expression, and AE struggled when it was enabled but not previewing, but on preview, it seems to work fine:

x = 0;
found = false;
for (var x = 0; x < thisComp.width; x++) {
    var sampleColor = thisComp.layer("sample").sampleImage([x, 540], [1, 1]);
    if (sampleColor[0] == 1) {
        found = true;
		break;
    }
}
x;

 

Just disable the expression when you're working on the other elements of the comp.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

the idea is to apply the code on several layers to read the color information of an underlying layer to calculate the distance to that point. This information will then be used to drive other expressions. 

So to code needs to be slim enough to run on several several layers at the same time. 

 

Perhaps there is a better way to find the point at where this underlying layer is white? 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

I think I'd be tempted to track the white points instead.  That will get you usable data, you can run the tracker for each white point and AE will be more manageable.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

There are no actual points per se, the approach right now is just to move by a small increment until the color white on the layer is discovered. Perhaps I could do I larger search radius or look at one line at the time? 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

Sample Image looks at all four values for color (RGBA) and returns an array with four values with a range of zero to one.  I would use an if statement that looks at the color and moves the sample point one pixel at a time, starting from the left edge of the comp.  You need time or time-inPoint for that. If you want the same Y position then the part of the expression that moves the sample point across the comp would look like this:

 

 

f = (time - inPoint) / thisComp.frameDuration;
p = [f, thisComp.height/2];

 

 

That is going to move the sample point or a null layer one pixel to the right for every frame starting from the first frame of the layer with the expression. 

 

Your for statement is going to sample every column of pixels in the comp for every frame and that's going to take some time.

 

Your if statement also needs to include the first three channels (RGB). It would look something like this:

 

 

smpl = spl.sampleImage(p, [.5, .5]);
if (smpl[0] == 1 && smpl[1] == 1 && smpl[2] == 1){
	stop moving;
}
else{
	keep moving;
}

 

 

Just looking at the red channel could give you a false stop. Using Time to drive the movement of the sample point will fix the recursive nature of the expression that kills performance. 

 

If you need to find the first white pixels in a frame and take a measurement, and the pixels don't change over time, then a better approach might be to move the sample point to the right until it reaches pixels with a [1, 1, 1, 1] value and only look at the first frame. I would have to think about how to do that.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

Thanks Rick for your brain on this. Although the step movement is not something that should be visible - I just want to cover the entire comp width starting from 0 until the white color is discovered. This needs to be calculated at every frame for it to be dynamically updated.  

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

I think you are stuck with recursive expressions. For a 4K comp, I'm getting a render time of more than 40 seconds per frame. Put that on ten layers, and you're dead in the water.

 

Unless Dan Ebberts can come up with a better solution, it's beyond me.  

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 07, 2023 Apr 07, 2023

Copy link to clipboard

Copied

If you have time to track each layer you want to analyze, you can open Mocha AE, select the white area on the layer, set tracking to Translation only, verify the position of the track by enabling surface, track, and then just drag the pickwhip to the Top Right X position to get the position of the white area as it moves around the screen. 

 

As long as there is sufficient white on the layer to track the edge, you should be fine. It won't be automatic, but it only takes a couple of minutes for Mocha AE to do a very accurate translation-only surface track. Here's a simple example with a moving white bar:

RickGerard_1-1680883059164.gif

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Apr 08, 2023 Apr 08, 2023

Copy link to clipboard

Copied

LATEST

Update: 

I have something that sort of works, I used the updated code from ShiveringCactus and modified it. 

 

 

 

found = false; 
for (x = 500; x < thisComp.width-100; x += thisComp.layer("sample precomp 2").effect("resolution")("Slider")) {
sample = thisComp.layer("sample precomp 2").sampleImage([x, transform.yPosition], [1,1]);
if (sample[0] == 1) {
		found = true;
		break;
	}
}
[linear(x, 0, 1080, 0, 238), value[1]];

 

 

I have a slider with a "resolution" value letting me choose how many steps it should take at each frame. I also modified it to start at x = 500 and end -100 from the comp width. It sort of works at several layers but AE crashes from time to time. 

 

Maybe someone has further suggestions on how to improve this approach...

 

It's applied to the scale, that's why I'm using a two dimensional value as the result. 

 

Also @Rick Gerard since I'm only looking for white right now it works fine to just use one of tha channels from sampleImage. 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines