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

Selecting the brightest pixels

Explorer ,
Sep 07, 2014 Sep 07, 2014

Hello

Is it possible to write a script that finds brightest pixel or pixels (if there are more of them at the same brightness) in an active layer and selects them?

if there is an easier way to do that, (without writing a script) please tell me how...

TOPICS
Actions and scripting
8.4K
Translate
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
Adobe
Community Expert ,
Sep 17, 2014 Sep 17, 2014

I have a question is it possible to make this script use the value that It alerts me of in Threshold?

Of course.

• You need to select the Channel.

In the DOM activeDocument.activeChannels can be used for this, but keep in mind that this needs an Array!

• Then you should put theIndex in the line

desc33.putInteger( idLvl, 12 );

instead of the originally recorded value.

• Then load the Channel as a Selection (check out the Class "Selection" in ESTK’s Object Model Viewer to see how one can load a channel as a Selection).

• after that you can remove the Channel

Translate
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
Explorer ,
Sep 22, 2014 Sep 22, 2014

Hey Christoph, first of all thank you for helping me out...i appreciate your patience

im going to continue asking you questions

as i understand you instructed me to select the channel after i run the script your wrote... but i dont know how to do that... i tried to use this object model viewer... but im not even sure how to use it.. as you see (image 1) i tried to find out how to select the channel, but i see no codes..? please guide me

In the DOM activeDocument.activeChannels can be used for this, but keep in mind that this needs an Array!

i really dont understand this sentence.. what is DOM? also i looked up ARRAY...[Definition: In math, an array refers to a set of numbers or objects that will follow a specific pattern. An array is an orderly arrangement, often in rows, columns or a matrix] why should i keep this in mind?


• Then you should put theIndex in the line

you mean i should put this line at the end of this code?

instead of the originally recorded value.

I dont understand what is the originally recorded value?

• Then load the Channel as a Selection (check out the Class "Selection" in ESTK’s Object Model Viewer to see how one can load a channel as a Selection)

Again i looked at the object model viewer.. not sure i understand what to look at? (image 2)

1.jpg

2.jpg

Translate
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 ,
Sep 22, 2014 Sep 22, 2014
i really dont understand this sentence.. what is DOM? also i looked up ARRAY

DOM stands for Document Object Model and is contrasted against Action Manager code (the one recorded with ScriptingListener.plugin).

An Array in JavaScript can be a collection of Numbers, Strings, Arrays, … and can be signified by square brackets.

So to create an Array of the last Channel

var theArray = [app.activeDocuments.channels[app.activeDocuments.channels.length - 1]];

I dont understand what is the originally recorded value?

The value you used in the Threshold operation when you recorded it.

Again i looked at the object model viewer.. not sure i understand what to look at? (image 2)

You had looked up

Selection.load

What arguments does this take?

A Channel, SelectionType and a boolean argument.

(Edit: In the brackets after "activeDocument.selection.load" you need to indicate the channel to load, how the Selection will be combined with a potentially existing Selection and whether it should be inverted.)

Translate
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
Explorer ,
Sep 22, 2014 Sep 22, 2014

Sorry im still lost... what is....

an Array of the last Channel

and please tell me what does this code do? and what i should to do with it?

var theArray = [app.activeDocuments.channels[app.activeDocuments.channels.length - 1]];

and still, please tell me where did you get this from?

Selection.load

and do i put this code into this one? like this?

var theArray = [app.activeDocuments.Selection.load[app.activeDocuments.Selection.load.length - 1]];

The only thing i think i understand is that i take this code from the last line of the script you wrote

2.jpg

and paste it instead of number 12?

#target photoshop

// check the histogram;

var theHist = activeDocument.channels[activeDocument.channels.length - 1].histogram;

var theCheck = false;

var theIndex = 255;

while (theCheck == false) {

var thePixels = theHist[theIndex];

// if the value has more than one pixels;

if (thePixels > 0) {var theCheck = true};

theIndex--

};

alert (theIndex);

// =======================================================

var idThrs = charIDToTypeID( "Thrs" );

    var desc33 = new ActionDescriptor();

    var idLvl = charIDToTypeID( "Lvl " );

    desc33.putInteger( idLvl, theIndex );

executeAction( idThrs, desc33, DialogModes.NO );

the script seems to be working.. and it seems it takes the threshold value and uses it to create a channel..which is great...

here im not sure what i should do...

(Edit: In the brackets after "activeDocument.selection.load" you need to indicate the channel to load, how the Selection will be combined with a potentially existing Selection and whether it should be inverted.)

and where did you get this from?

activeDocument.selection.load

Translate
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 ,
Sep 22, 2014 Sep 22, 2014

and what i should to do with it?

You should use it to select that Channel.

activeDocument.activeChannels = theArray;

var theArray = [app.activeDocuments.Selection.load[app.activeDocuments.Selection.load.length - 1]];

That’s nonsense, a method (like load) needs brackets, not square brackets and there is no need to define the Selection as an Array (or call it theArray).


Selection does not exist on its own, it exists only with a document.

So to load a Channel you need to reference the document:

activeDocument.selection.load()

And in the brackets note the Channel, the SelectionType and the boolean argument for inverting.

If you do not understand the OMV yet I recommend you search for sample Scripts.

For example a search on this Forum for "selection.load" pointed to this:

Re: Is this possible? crop selection....?

Translate
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 ,
Sep 22, 2014 Sep 22, 2014

You should use it to select that Channel.

By this I mean "select the Channel", not "load the Channel as a Selection".

Translate
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
Explorer ,
Sep 22, 2014 Sep 22, 2014

First can you please tell me what im missing to achieve selection of the brightest pixel or pixels? because im getting confused

now, I have this code...

#target photoshop

// check the histogram;

var theHist = activeDocument.channels[activeDocument.channels.length - 1].histogram;

var theCheck = false;

var theIndex = 255;

while (theCheck == false) {

var thePixels = theHist[theIndex];

// if the value has more than one pixels;

if (thePixels > 0) {var theCheck = true};

theIndex--

};

alert (theIndex);

// =======================================================

var idThrs = charIDToTypeID( "Thrs" );

    var desc33 = new ActionDescriptor();

    var idLvl = charIDToTypeID( "Lvl " );

    desc33.putInteger( idLvl, theIndex );

executeAction( idThrs, desc33, DialogModes.NO );

activeDocument.activeChannels = theArray;

please tell me in order what's left to do?

- To select the channel

- Load the channel

- ...

Translate
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 ,
Sep 22, 2014 Sep 22, 2014

You need to select the Channel to which you want to apply Threshold.

Translate
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 ,
Sep 22, 2014 Sep 22, 2014

And after applying Threshold you need to load the Channel as a Selection.

Translate
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
Explorer ,
Sep 22, 2014 Sep 22, 2014

But i thought that this part of the code has already applied threshold.. no?

// =======================================================

var idThrs = charIDToTypeID( "Thrs" );

    var desc33 = new ActionDescriptor();

    var idLvl = charIDToTypeID( "Lvl " );

    desc33.putInteger( idLvl, theIndex );

executeAction( idThrs, desc33, DialogModes.NO );

activeDocument.activeChannels = theArray;

Translate
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 ,
Sep 22, 2014 Sep 22, 2014

But to the active Channel/s.

Is the last Channel already selected?

Translate
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
Explorer ,
Sep 23, 2014 Sep 23, 2014

the last channel is selected after i run the script and also before i run the script, because i use calculations command.. so before i run this script

#target photoshop

// check the histogram;

var theHist = activeDocument.channels[activeDocument.channels.length - 1].histogram;

var theCheck = false;

var theIndex = 255;

while (theCheck == false) {

var thePixels = theHist[theIndex];

// if the value has more than one pixels;

if (thePixels > 0) {var theCheck = true};

theIndex--

};

// =======================================================

var idThrs = charIDToTypeID( "Thrs" );

    var desc33 = new ActionDescriptor();

    var idLvl = charIDToTypeID( "Lvl " );

    desc33.putInteger( idLvl, theIndex );

executeAction( idThrs, desc33, DialogModes.NO );

i use calculations and get this

Untitled-1.jpg

then i run the script and get this

Untitled-2.jpg

Please tell me what's left to do? how would you select the brightest pixel/pixels?

Translate
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 ,
Sep 23, 2014 Sep 23, 2014

Use

activeDocument.selection.load(/*insert the Channel here*/, SelectionType.REPLACE, false)

Translate
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
Explorer ,
Sep 24, 2014 Sep 24, 2014

Please tell me how do i use it? do i just place it at the ned of the script? and what does it do? and please tell me whats left to do..it doesnt have to be a script... is it possible to finish it as an action? just please tell me the method? how do you select the brightest pixel/pixels?

active document try.jpg

Translate
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 ,
Sep 24, 2014 Sep 24, 2014

I have told you to use the line

activeDocument.selection.load(/*insert the Channel here*/, SelectionType.REPLACE, false)

and insert the channel at the appropriate place (where not "/*insert the Channel here*/" stands).

Translate
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 ,
Sep 24, 2014 Sep 24, 2014
and please tell me whats left to do.

The stuff leading up to this (Calculations, hiding other Layers if necessary, selecting the Channel, …) can be included in the Script.

You can record the steps with ScriptingListener.plugin and insert (and if necessary amend) the code you get from that.

Translate
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
Explorer ,
Sep 24, 2014 Sep 24, 2014

Dear Christoph I assume you think i understand more than i actually do. Im asking you to forgive my ignorance, but I dont understand as much as you might expect from me. Im not lazy to improve myself, but this stuff is too advanced for me to grasp it. I can only do guesses. You asked me to insert a channel, and i have no idea what you mean. I think my poor english might be adding to my confusion. And i get frustrated at times because i feel im not getting anywhere and never will. I feel like im annoying you with my never ending questions,  but then i see no other way.

Now since you explained a little bit more i think i understand that "/*insert the Channel here*/" is a note you left for me? Initially i thought it's a part of the code. So i guess you asking me to insert the name of the active channel? So instead of /*insert the Channel here*/ i write "Alpha 1"? or do i copy from script listener and paste it? which one is correct?

insert 1.jpg

insert 2.jpg

Translate
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 ,
Sep 24, 2014 Sep 24, 2014

The name alone is not enough, you need to define the Channel.

For example

activeDocument.channels[activeDocument.channels.length - 1]

signifies the last Channel.

activeDocument.channels[0]

the first (in an RGB image the red one).

If you want to select a Channel based on its name use

activeDocument.channels.getByName(/* insert the name here */)

But to avoid having to write activeDocument over and over again one usually does something like

var theDoc = app.activeDocument

and subsequently uses the variable (in this case called "theDoc").

And yes, the parts between "/*" and "*/" are comments that do not perform as code.

Another way to comment something out is to start a line with "//".

Translate
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
Explorer ,
Sep 24, 2014 Sep 24, 2014

Dear Christoph, can i ask you to write this code for me? I havent forgotten that you have already helped me a lot. And i know what you have told me, and i know what i have told you. I should learn! I should learn to do my scripts myself. And i will once i have a little more time. But im working on this project and i need to have it done quite soon. And right now it is not looking good. in fact, it's looking pretty bad. And what is even worse is that I havent been working on it since i posted this issue. It has been more than two weeks since im stuck over this thing - selecting brightest pixel. Would you be so kind to give me the "correct answer" please? Im asking you this because, even with your help along, i fear it might take ages until i have this script done.....please I beg you...i would appreciate that so much

Translate
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
Explorer ,
Sep 26, 2014 Sep 26, 2014

I understand your decision. You are a man of word and i respect that. i dont expect you to write this script. But can you at least explain the idea behind it? Can you explain in detail how it is done in a manual mode? I might find someone who will write the sript but i first need to know how it works, because i still, by this point, not sure i see how it selects the brightest pixel? That would be very helpful

Translate
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 ,
Sep 26, 2014 Sep 26, 2014

I am not that stubborn but work has picked up; I may get to posting on the weekend.

The process is as follows:

By the Calculation of the same gray source as normal one simply produces a Channel representing the luminance (of the image or the Layer).

The Histogram indicates which is the first color value that is non zero, so actually represented by pixels.

That value used in Threshold on the Channel makes those pixels white and all other pixels black.

Then one can manually load that Channel as a Selection (manually by cmd-clicking it).

An unforeseen issue: In Layers that have transparency the wholly transparent regions are represented as white – but this is solvable.

Other than that transparency is disregarded in the Calculation – so one should bear in mind that a light pixel in a very much transparent region still counts.

Translate
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 ,
Sep 27, 2014 Sep 27, 2014

// creates a selection based on the active layer’s lightest pixels;

// 2014, use it at your own risk;

#target photoshop

if (app.documents.length > 0) {

var myDocument = app.activeDocument;

var theIndex = getDocumentIndex();

// check layer;

var ref = new ActionReference();

ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

var layerDesc = executeActionGet(ref);

if (layerDesc.hasKey(stringIDToTypeID("layerKind")) == true) {var layerKind = layerDesc.getInteger(stringIDToTypeID("layerKind"))}

else {var layerKind = 1};

var layerIndex = layerDesc.getInteger(stringIDToTypeID("itemIndex"));

var isBackground = layerDesc.getBoolean(stringIDToTypeID("background"));

if (myDocument.layers[myDocument.layers.length - 1].isBackgroundLayer == true) {layerIndex--};

// proceed for artlayers and smart objects;

if (layerKind == 1 || layerKind == 5) {

// calculate layer gray and transparency;

// =======================================================

var idMk = charIDToTypeID( "Mk  " );

    var desc4 = new ActionDescriptor();

    var idNw = charIDToTypeID( "Nw  " );

    var idDcmn = charIDToTypeID( "Dcmn" );

    desc4.putClass( idNw, idDcmn );

    var idUsng = charIDToTypeID( "Usng" );

        var desc5 = new ActionDescriptor();

        var idT = charIDToTypeID( "T   " );

            var ref4 = new ActionReference();

            ref4.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Gry " ) );

// if only background layer index does not work:

if (myDocument.layers.length > 1 || isBackground == false) {ref4.putIndex( charIDToTypeID( "Lyr " ), layerIndex )}

else {ref4.putProperty( charIDToTypeID( "Lyr " ), charIDToTypeID( "Bckg" ) )};

            var idDcmn = charIDToTypeID( "Dcmn" );

            ref4.putIndex( idDcmn, theIndex );

        desc5.putReference( idT, ref4 );

        var idSrctwo = charIDToTypeID( "Src2" );

            var ref5 = new ActionReference();

// background layer does not have transparency;

if (isBackground == false) {ref5.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Trsp" ) )}

else {ref5.putEnumerated( charIDToTypeID( "Chnl" ), charIDToTypeID( "Chnl" ), charIDToTypeID( "Gry " ) )};

// if only background layer index does not work:

if (myDocument.layers.length > 1 || isBackground == false) {ref5.putIndex( charIDToTypeID( "Lyr " ), layerIndex )}

else {ref5.putProperty( charIDToTypeID( "Lyr " ), charIDToTypeID( "Bckg" ) )};

            var idDcmn = charIDToTypeID( "Dcmn" );

            ref5.putIndex( idDcmn, theIndex );

        desc5.putReference( idSrctwo, ref5 );

    var idClcl = charIDToTypeID( "Clcl" );

    desc4.putObject( idUsng, idClcl, desc5 );

executeAction( idMk, desc4, DialogModes.NO );

// check the histogram;

var thisDocument = app.activeDocument;

var theChannel = thisDocument.channels[0];

var theHist = theChannel.histogram;

// search for first non zero value;

var theCheck = false;

var theIndex = 256;

while (theCheck == false) {

theIndex--

var thePixels = theHist[theIndex];

// if the value has more than one pixels;

if (thePixels > 0) {var theCheck = true};

};

// apply threshold;

applyThreshold (theIndex);

// get index;

var thisIndex = getDocumentIndex();

// switch documents and load selection;

app.activeDocument = myDocument;

// =======================================================

var idsetd = charIDToTypeID( "setd" );

    var desc7 = new ActionDescriptor();

    var idnull = charIDToTypeID( "null" );

        var ref7 = new ActionReference();

        var idChnl = charIDToTypeID( "Chnl" );

        var idfsel = charIDToTypeID( "fsel" );

        ref7.putProperty( idChnl, idfsel );

    desc7.putReference( idnull, ref7 );

    var idT = charIDToTypeID( "T   " );

        var ref8 = new ActionReference();

        var idChnl = charIDToTypeID( "Chnl" );

        var idOrdn = charIDToTypeID( "Ordn" );

        var idTrgt = charIDToTypeID( "Trgt" );

        ref8.putEnumerated( idChnl, idOrdn, idTrgt );

        ref8.putIndex( charIDToTypeID( "Dcmn" ), thisIndex );

    desc7.putReference( idT, ref8 );

executeAction( idsetd, desc7, DialogModes.NO );

// close document;

app.activeDocument = thisDocument;

thisDocument.close(SaveOptions.DONOTSAVECHANGES)

}

else {alert ("please select a pixel layer")}

};

////// threshold //////

function applyThreshold (theValue) {

// =======================================================

var idThrs = charIDToTypeID( "Thrs" );

    var desc7 = new ActionDescriptor();

    desc7.putInteger( charIDToTypeID( "Lvl " ), theValue );

executeAction( idThrs, desc7, DialogModes.NO );

};

////// get index //////

function getDocumentIndex () {

var ref = new ActionReference();

ref.putEnumerated( charIDToTypeID("Dcmn"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );

var docDesc = executeActionGet(ref);

var theIndex = docDesc.getInteger(stringIDToTypeID("itemIndex"));

return theIndex

};

edited on 2014-10-02

Translate
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
Explorer ,
Oct 06, 2014 Oct 06, 2014

May i expect you to fix this code in the near future or it's quite complicated?

Translate
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 ,
Oct 07, 2014 Oct 07, 2014

I have posted the code in open form, so I would have hoped you figure out and rectify the mistake yourself. (But the mistake was not a didactic means, it did happen involuntarily.)


Yes, there was a mistake – the while-clause does not terminate at changing the variable "theCheck" but when it closes (with the "}" bracket) so "theIndex" was reduced by 1 after meeting the condition.

So the options are

• starting ""theIndex" at 256 and subtracting at the beginning instead of the end of the while-clause or

• adding 1 to "theIndex" when using it in "applyThreshold"

Translate
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
Explorer ,
Oct 12, 2014 Oct 12, 2014

Can you please tell me what do you mean by saying "the-while clause"?

Translate
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