How can I make sampleImage sample a mask instead of a set radius?
Someone here kindly wrote me a script, that I've tweaked with ChatGPT.
The role of my script is to scan a radius for brightness, scrub through the video and detect the lightest and darkest frame in that video, and find the mid-point between those two brightnesses. I also make it do a couple of other things that aren't so relevant to this.
The thing is, I want it to sample inside a mask I have, instead of in a set radius. I tried doing this through ChatGPT, and it did end up using the mask as a reference, but it only sampled a single pixel from the center of the mask, when I need it to sample all the pixels in the mask. As soon as I tried to make it so that it sampled all the pixels, it was laden with error messages, and became stupidly complicated.
TL;DR: How can I make the sampleImage sample all the pixels (not just one) in a specified mask, instead of a set radius?
function getLightestAndDarkest() {
var frameScan = 300;
var sampleRadius = 500;
var brightnessThreshold = 0.1;
var comp = app.project.activeItem;
if (comp && comp instanceof CompItem) {
var layer = comp.selectedLayers[0];
var pt = [layer.width / 2, layer.height / 2];
var lightExpr = "s = sampleImage([" + pt[0] + "," + pt[1] + "],[" + sampleRadius + "," + sampleRadius + "],false,time);\rrgbToHsl(s)[2];";
var slider = layer.property("Effects").addProperty("ADBE Slider Control");
slider.property("ADBE Slider Control-0001").expression = lightExpr;
var sliderMin = 1;
var sliderMax = 0;
var frameMin = 0;
var frameMax = 0;
var frameMid = 0;
var f = 0;
var t = 0;
var curVal;
var midVal;
var skinGlowLayer = comp.layer("Skin Glow");
var lightestSlider = skinGlowLayer.effect("Lightest Frame")("Slider");
var darkestSlider = skinGlowLayer.effect("Darkest Frame")("Slider");
// Remove existing markers with specified names
var markerProperty = layer.property("Marker");
var numMarkers = markerProperty.numKeys;
for (var i = numMarkers; i >= 1; i--) {
var markerComment = markerProperty.keyValue(i).comment;
if (markerComment.indexOf("Lightest") == 0 || markerComment.indexOf("Darkest") == 0 || markerComment.indexOf("Mid") == 0) {
markerProperty.removeKey(i);
}
}
while (t < comp.duration) {
curVal = slider.property("ADBE Slider Control-0001").valueAtTime(t, false);
if (curVal > sliderMax && curVal > brightnessThreshold) {
sliderMax = curVal;
frameMax = f;
}
if (curVal < sliderMin && curVal > brightnessThreshold) {
sliderMin = curVal;
frameMin = f;
}
f += frameScan;
t = f * comp.frameDuration;
}
midVal = (sliderMax + sliderMin) / 2;
f = 0;
t = 0;
var closestVal = 1;
while (t < comp.duration) {
curVal = slider.property("ADBE Slider Control-0001").valueAtTime(t, false);
if (Math.abs(curVal - midVal) < Math.abs(closestVal - midVal)) {
closestVal = curVal;
frameMid = f;
}
f += frameScan;
t = f * comp.frameDuration;
}
slider.remove();
lightestSlider.setValue(frameMax);
darkestSlider.setValue(frameMin);
var marker = new MarkerValue("Lightest - " + frameMax.toLocaleString());
layer.property("Marker").setValueAtTime(frameMax * comp.frameDuration, marker);
marker = new MarkerValue("Darkest - " + frameMin.toLocaleString());
layer.property("Marker").setValueAtTime(frameMin * comp.frameDuration, marker);
marker = new MarkerValue("Mid-point - " + frameMid.toLocaleString());
layer.property("Marker").setValueAtTime(frameMid * comp.frameDuration, marker);
alert("Lightest frame = " + frameMax + "\nDarkest frame = " + frameMin + "\nMid-point frame = " + frameMid);
} else {
alert("No comp active.");
}
}
getLightestAndDarkest();
