Highlighted

## Histogram passed and drawn into a Layer. Done!

Enthusiast ,
Dec 14, 2017

Copied

Hi, I have made an exercise that can be usefull to someone.

On a active image, it builds and draws the histograms on several layers.

This works only on RGB images and if they have more than 8bits/channel, it will reduce to 8bit/channel before proced.

I used this on windows 10 and CC(2017)

Enjoy or complete and develop it as you want.

This next code will build 4 layers

1 -  the 3 rgb channels coloured histogram

2 - the Max(, , ) Luminosity RGB histogram (gets the max value of each channel)

3 - the 8bit Lightness channel Lab histogram (the image will be reverted again to RGB afterwards)

4 - 8bit Luminosity RGB histogram

`addHistogram(true); // this draws a layer with a coloured 8bit RGB histogram addHistogram(false, false, true); //  this draws the Max(, , ) Luminosity RGB histogram (gets the max value of each channel)addHistogram(false, true); // this draws a layer with 8bit Lightness channel Lab histogram addHistogram(false, false); // this draws a layer with 8bit Luminosity RGB histogram ///////////////////////////////  HISTOGRAM IN LAYER   ///////////////////////////////////function addHistogram(RGB, Lab, MaxRGB) {    ///////////////////////////////////////////////// createProgressWindow    var createProgressWindow = function(title, message, hasCancelButton) {      var win;      if (title == null) title = "Work in progress";      if (message == null) message = "Please wait...";      if (hasCancelButton == null) hasCancelButton = false;      win = new Window("palette", "" + title, undefined);      win.bar = win.add("progressbar", {x: 20, y: 12, width: 300, height: 20 }, 0, 100);      win.stMessage = win.add("statictext", { x: 10, y: 36, width: 320, height: 20 }, "" + message);      win.stMessage.justify = 'center';        if (hasCancelButton) {        win.cancelButton = win.add('button', undefined, 'Cancel');        win.cancelButton.onClick = function() {          win.close();          throw new Error('User canceled the pre-processing!');        };      }      this.reset = function(message) {        win.bar.value = 0;        win.stMessage.text = message;        return win.update();      };      this.updateProgress = function(perc, message) {        if (perc != null) win.bar.value = perc;        if (message != null) win.stMessage.text = message;        return win.update();      };      this.close = function() {        return win.close();      };      win.center(win.parent);      return win.show();    };    //    // the other layer histograms, if exist, should be invisible so the reading is only on the pixels of the image itself    if (getLayer("RGB histogram")) activeDocument.artLayers.getByName ("RGB histogram").visible = false;    if (getLayer("Lightness Lab histogram")) activeDocument.artLayers.getByName ("Lightness Lab histogram").visible = false;    if (getLayer("Luminosity RGB")) activeDocument.artLayers.getByName ("Luminosity RGB").visible = false;    if (getLayer("Luminosity Max")) activeDocument.artLayers.getByName ("Luminosity Max").visible = false;    //    var layerName = (RGB) ? "RGB histogram" : ((Lab) ? "Lightness Lab histogram" : ((MaxRGB) ? "Luminosity Max" : "Luminosity RGB"));      //    if (!getLayer(layerName)) {        // it works only on RGB images        if (activeDocument.mode == DocumentMode.RGB) {            // if the image is 16bit/channel or more it sets 8bits/channel before read the histogram            if (!activeDocument.bitsPerChannel == BitsPerChannelType.EIGHT) activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;            \$.writeln(layerName);            var wasHereLayer = activeDocument.activeLayer;            var unitsAntes = app.preferences.rulerUnits;            var foregroundPreviousColor = app.foregroundColor;            app.preferences.rulerUnits = Units.PIXELS; // importante            activeDocument.quickMaskMode = false;            activeDocument.selection.deselect();            //            // read histogram:            var hL = activeDocument.histogram;            var hR = activeDocument.channels["Red"].histogram;            var hG = activeDocument.channels["Green"].histogram;            var hB = activeDocument.channels["Blue"].histogram;            // if you want the Luminosity of Lab, export it to Lab, read it, and revert it to RGB            if (Lab) {                activeDocument.changeMode (ChangeMode.LAB);                // read Lightness channel histogram of Lab                 var hL = activeDocument.channels["Lightness"].histogram;                // revert to RGB                activeDocument.changeMode (ChangeMode.RGB);            } else {                // read Luminosity composite channel histogram of RGB                 var hL = activeDocument.histogram;            }            //            var ww = activeDocument.width.as('px');            var hh = activeDocument.height.as('px');            var totalPixels = ww*hh;            var totalPixels1Col = totalPixels/256;            //             var pBar = new createProgressWindow("Histogram building...", "Please wait", false);            //             activeDocument.artLayers.add();            activeDocument.activeLayer.name = layerName;            activeDocument.activeLayer.move( activeDocument, ElementPlacement.PLACEATBEGINNING );            activeDocument.activeLayer.blendMode = BlendMode.NORMAL; // blending mode "normal"            activeDocument.activeLayer.opacity = 60; // opacity 60%            //            var hhGraph = 60;            var hY = 400; // base y of graph            var hX = 100; // base x of graph            // base transparent            app.foregroundColor.rgb.red = 0;            app.foregroundColor.rgb.green = 0;            app.foregroundColor.rgb.blue = 0;            //            drawSelectionScreen (hX-2, hY+2, 258+hX, hY-322);            // fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]             app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 40, false);            activeDocument.selection.deselect();            //            var myHist = [];            //            if (RGB) {                for (var a in activeDocument.componentChannels) {                    //  criar as 3 cores R, G e B e o graph da cada uma                    (a==0) ? app.foregroundColor.rgb.red = 255 : app.foregroundColor.rgb.red = 0;                    (a==1) ? app.foregroundColor.rgb.green = 255 : app.foregroundColor.rgb.green = 0;                    (a==2) ? app.foregroundColor.rgb.blue = 255 : app.foregroundColor.rgb.blue = 0;                    //                     if (a==0) myHist = hR;                    if (a==1) myHist = hG;                    if (a==2) myHist = hB;                    //                    for ( i = 0; i <= 255; i++ ) {                        var col = i+hX;                        var YYY = Math.min(Math.floor(myHist*hhGraph/totalPixels1Col), 320);                        drawSelectionScreen (col, hY, col+1, hY-YYY);                        //                        var percent = Math.floor(((i+1)+(a*256))*100/768);                        pBar.updateProgress (percent, activeDocument.componentChannels.name.toUpperCase() + " Channel " + percent+ " % completed");                    }                    // fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]                     app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);                    activeDocument.selection.deselect();                }            } else {                app.foregroundColor.rgb.red = 255;                app.foregroundColor.rgb.green = 255;                app.foregroundColor.rgb.blue = 255;                myHist = hL;                for ( i = 0; i <= 255; i++ ) {                    var col = i+hX;                    if (MaxRGB) {                        var YYY = Math.min(Math.floor(Math.max(hR, hG, hB)*hhGraph/totalPixels1Col), 320);                    } else {                        var YYY = Math.min(Math.floor(myHist*hhGraph/totalPixels1Col), 320);                    }                    drawSelectionScreen (col, hY, col+1, hY-YYY);                    //                    var percent = Math.floor((i+1)*100/256);                    pBar.updateProgress (percent, "Luminosity Channel " + percent+ " % completed");                }                // fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]                 app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);                activeDocument.selection.deselect();            }            pBar.close();            // activeDocument.activeLayer = wasHereLayer;            app.preferences.rulerUnits = unitsAntes;            app.foregroundColor = foregroundPreviousColor;            \$.gc();        } else {            alert("Must be an RGB image");        }    } else {        alert("Already has created this '" + layerName + "' layer!");        return;    }    function drawSelectionScreen(x1, y1, x2, y2) {        \$.level = 0;        try {            // SelectionType.SELECTEDAREA | DIMINISH | EXTEND | INTERSECT | REPLACE            activeDocument.selection.select([[ x1, y1], [x2, y1], [x2, y2], [x1,y2]], SelectionType.EXTEND, 0, false);        } catch(e) {}        \$.level = 1;    }    function drawLineScreen(x1, y1, x2, y2, width, transparency) {        \$.level = 0;        try {            var desc = new ActionDescriptor();            var lineDesc = new ActionDescriptor();            var startDesc = new ActionDescriptor();            startDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x1 );            startDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y1 );            lineDesc.putObject( charIDToTypeID('Strt'), charIDToTypeID('Pnt '), startDesc );            var endDesc = new ActionDescriptor();            endDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x2 );            endDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y2 );            lineDesc.putObject( charIDToTypeID('End '), charIDToTypeID('Pnt '), endDesc );            lineDesc.putUnitDouble( charIDToTypeID('Wdth'), charIDToTypeID('#Pxl'), width ); //             desc.putObject( charIDToTypeID('Shp '), charIDToTypeID('Ln  '), lineDesc );            desc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Scrn" ) ); // mode: Screen             desc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), transparency ); // [0-100] transparency            desc.putBoolean( charIDToTypeID('AntA'), false ); // important antialias should be false            executeAction( charIDToTypeID('Draw'), desc, DialogModes.NO );        } catch(e) {}        \$.level = 1;    }    //////////////////////////////////    function getLayer(layername) {        var result = false;        for (var a=0; a<activeDocument.artLayers.length ; a++) {            if (String(activeDocument.artLayers.name) == layername) {                result = true;                break;            }        }        return result;    }}`
TOPICS
Actions and scripting

Views

1.7K

Likes

Report

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

## Histogram passed and drawn into a Layer. Done!

Enthusiast ,
Dec 14, 2017

Copied

Hi, I have made an exercise that can be usefull to someone.

On a active image, it builds and draws the histograms on several layers.

This works only on RGB images and if they have more than 8bits/channel, it will reduce to 8bit/channel before proced.

I used this on windows 10 and CC(2017)

Enjoy or complete and develop it as you want.

This next code will build 4 layers

1 -  the 3 rgb channels coloured histogram

2 - the Max(, , ) Luminosity RGB histogram (gets the max value of each channel)

3 - the 8bit Lightness channel Lab histogram (the image will be reverted again to RGB afterwards)

4 - 8bit Luminosity RGB histogram

`addHistogram(true); // this draws a layer with a coloured 8bit RGB histogram addHistogram(false, false, true); //  this draws the Max(, , ) Luminosity RGB histogram (gets the max value of each channel)addHistogram(false, true); // this draws a layer with 8bit Lightness channel Lab histogram addHistogram(false, false); // this draws a layer with 8bit Luminosity RGB histogram ///////////////////////////////  HISTOGRAM IN LAYER   ///////////////////////////////////function addHistogram(RGB, Lab, MaxRGB) {    ///////////////////////////////////////////////// createProgressWindow    var createProgressWindow = function(title, message, hasCancelButton) {      var win;      if (title == null) title = "Work in progress";      if (message == null) message = "Please wait...";      if (hasCancelButton == null) hasCancelButton = false;      win = new Window("palette", "" + title, undefined);      win.bar = win.add("progressbar", {x: 20, y: 12, width: 300, height: 20 }, 0, 100);      win.stMessage = win.add("statictext", { x: 10, y: 36, width: 320, height: 20 }, "" + message);      win.stMessage.justify = 'center';        if (hasCancelButton) {        win.cancelButton = win.add('button', undefined, 'Cancel');        win.cancelButton.onClick = function() {          win.close();          throw new Error('User canceled the pre-processing!');        };      }      this.reset = function(message) {        win.bar.value = 0;        win.stMessage.text = message;        return win.update();      };      this.updateProgress = function(perc, message) {        if (perc != null) win.bar.value = perc;        if (message != null) win.stMessage.text = message;        return win.update();      };      this.close = function() {        return win.close();      };      win.center(win.parent);      return win.show();    };    //    // the other layer histograms, if exist, should be invisible so the reading is only on the pixels of the image itself    if (getLayer("RGB histogram")) activeDocument.artLayers.getByName ("RGB histogram").visible = false;    if (getLayer("Lightness Lab histogram")) activeDocument.artLayers.getByName ("Lightness Lab histogram").visible = false;    if (getLayer("Luminosity RGB")) activeDocument.artLayers.getByName ("Luminosity RGB").visible = false;    if (getLayer("Luminosity Max")) activeDocument.artLayers.getByName ("Luminosity Max").visible = false;    //    var layerName = (RGB) ? "RGB histogram" : ((Lab) ? "Lightness Lab histogram" : ((MaxRGB) ? "Luminosity Max" : "Luminosity RGB"));      //    if (!getLayer(layerName)) {        // it works only on RGB images        if (activeDocument.mode == DocumentMode.RGB) {            // if the image is 16bit/channel or more it sets 8bits/channel before read the histogram            if (!activeDocument.bitsPerChannel == BitsPerChannelType.EIGHT) activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;            \$.writeln(layerName);            var wasHereLayer = activeDocument.activeLayer;            var unitsAntes = app.preferences.rulerUnits;            var foregroundPreviousColor = app.foregroundColor;            app.preferences.rulerUnits = Units.PIXELS; // importante            activeDocument.quickMaskMode = false;            activeDocument.selection.deselect();            //            // read histogram:            var hL = activeDocument.histogram;            var hR = activeDocument.channels["Red"].histogram;            var hG = activeDocument.channels["Green"].histogram;            var hB = activeDocument.channels["Blue"].histogram;            // if you want the Luminosity of Lab, export it to Lab, read it, and revert it to RGB            if (Lab) {                activeDocument.changeMode (ChangeMode.LAB);                // read Lightness channel histogram of Lab                 var hL = activeDocument.channels["Lightness"].histogram;                // revert to RGB                activeDocument.changeMode (ChangeMode.RGB);            } else {                // read Luminosity composite channel histogram of RGB                 var hL = activeDocument.histogram;            }            //            var ww = activeDocument.width.as('px');            var hh = activeDocument.height.as('px');            var totalPixels = ww*hh;            var totalPixels1Col = totalPixels/256;            //             var pBar = new createProgressWindow("Histogram building...", "Please wait", false);            //             activeDocument.artLayers.add();            activeDocument.activeLayer.name = layerName;            activeDocument.activeLayer.move( activeDocument, ElementPlacement.PLACEATBEGINNING );            activeDocument.activeLayer.blendMode = BlendMode.NORMAL; // blending mode "normal"            activeDocument.activeLayer.opacity = 60; // opacity 60%            //            var hhGraph = 60;            var hY = 400; // base y of graph            var hX = 100; // base x of graph            // base transparent            app.foregroundColor.rgb.red = 0;            app.foregroundColor.rgb.green = 0;            app.foregroundColor.rgb.blue = 0;            //            drawSelectionScreen (hX-2, hY+2, 258+hX, hY-322);            // fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]             app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 40, false);            activeDocument.selection.deselect();            //            var myHist = [];            //            if (RGB) {                for (var a in activeDocument.componentChannels) {                    //  criar as 3 cores R, G e B e o graph da cada uma                    (a==0) ? app.foregroundColor.rgb.red = 255 : app.foregroundColor.rgb.red = 0;                    (a==1) ? app.foregroundColor.rgb.green = 255 : app.foregroundColor.rgb.green = 0;                    (a==2) ? app.foregroundColor.rgb.blue = 255 : app.foregroundColor.rgb.blue = 0;                    //                     if (a==0) myHist = hR;                    if (a==1) myHist = hG;                    if (a==2) myHist = hB;                    //                    for ( i = 0; i <= 255; i++ ) {                        var col = i+hX;                        var YYY = Math.min(Math.floor(myHist*hhGraph/totalPixels1Col), 320);                        drawSelectionScreen (col, hY, col+1, hY-YYY);                        //                        var percent = Math.floor(((i+1)+(a*256))*100/768);                        pBar.updateProgress (percent, activeDocument.componentChannels.name.toUpperCase() + " Channel " + percent+ " % completed");                    }                    // fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]                     app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);                    activeDocument.selection.deselect();                }            } else {                app.foregroundColor.rgb.red = 255;                app.foregroundColor.rgb.green = 255;                app.foregroundColor.rgb.blue = 255;                myHist = hL;                for ( i = 0; i <= 255; i++ ) {                    var col = i+hX;                    if (MaxRGB) {                        var YYY = Math.min(Math.floor(Math.max(hR, hG, hB)*hhGraph/totalPixels1Col), 320);                    } else {                        var YYY = Math.min(Math.floor(myHist*hhGraph/totalPixels1Col), 320);                    }                    drawSelectionScreen (col, hY, col+1, hY-YYY);                    //                    var percent = Math.floor((i+1)*100/256);                    pBar.updateProgress (percent, "Luminosity Channel " + percent+ " % completed");                }                // fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]                 app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);                activeDocument.selection.deselect();            }            pBar.close();            // activeDocument.activeLayer = wasHereLayer;            app.preferences.rulerUnits = unitsAntes;            app.foregroundColor = foregroundPreviousColor;            \$.gc();        } else {            alert("Must be an RGB image");        }    } else {        alert("Already has created this '" + layerName + "' layer!");        return;    }    function drawSelectionScreen(x1, y1, x2, y2) {        \$.level = 0;        try {            // SelectionType.SELECTEDAREA | DIMINISH | EXTEND | INTERSECT | REPLACE            activeDocument.selection.select([[ x1, y1], [x2, y1], [x2, y2], [x1,y2]], SelectionType.EXTEND, 0, false);        } catch(e) {}        \$.level = 1;    }    function drawLineScreen(x1, y1, x2, y2, width, transparency) {        \$.level = 0;        try {            var desc = new ActionDescriptor();            var lineDesc = new ActionDescriptor();            var startDesc = new ActionDescriptor();            startDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x1 );            startDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y1 );            lineDesc.putObject( charIDToTypeID('Strt'), charIDToTypeID('Pnt '), startDesc );            var endDesc = new ActionDescriptor();            endDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x2 );            endDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y2 );            lineDesc.putObject( charIDToTypeID('End '), charIDToTypeID('Pnt '), endDesc );            lineDesc.putUnitDouble( charIDToTypeID('Wdth'), charIDToTypeID('#Pxl'), width ); //             desc.putObject( charIDToTypeID('Shp '), charIDToTypeID('Ln  '), lineDesc );            desc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Scrn" ) ); // mode: Screen             desc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), transparency ); // [0-100] transparency            desc.putBoolean( charIDToTypeID('AntA'), false ); // important antialias should be false            executeAction( charIDToTypeID('Draw'), desc, DialogModes.NO );        } catch(e) {}        \$.level = 1;    }    //////////////////////////////////    function getLayer(layername) {        var result = false;        for (var a=0; a<activeDocument.artLayers.length ; a++) {            if (String(activeDocument.artLayers.name) == layername) {                result = true;                break;            }        }        return result;    }}`
TOPICS
Actions and scripting

Views

1.7K

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Dec 14, 2017 3
19 Replies 19
Dec 14, 2017

Copied

It worked perfectly on CS6 EXTENDED!

That new createProgressWindow() is something new for me I like visible incement. It works very fast (as far as panels are hidden, but that's normal). The end result makes only last layer is visible. Shouldn't all be checked? Anyway that is ok too

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Dec 14, 2017 0
Enthusiast ,
Dec 14, 2017

Copied

Hi,

I the function I created, I put all the existing histograms invisible so the next histogram when being created, it should not be affected by the colors added to the image  from the previous histograms.

Resume: the histograms should be build on the image colors and not the layer colors of the histograms.

In the end, the last histogram created should be visible and the previous invisible.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Dec 14, 2017 0
Community Beginner ,
Mar 22, 2018

Copied

Is it possible to do this for video footage?

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Mar 22, 2018 0
Enthusiast ,
Mar 22, 2018

Copied

I don't know if I understand the question.

You mean video within photoshop where you can get the histogram at any frame?

That should work in a single stoped frame.

In the meantime I have found that it is much faster to draw the histogram in a layer creating first all the vector data by code and on the layer 1 time in the end for each channel.

When I have time I can update the code.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Mar 22, 2018 1
Community Beginner ,
Mar 26, 2018

Copied

Is it possible to do this in After Effects for Video footage

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Mar 26, 2018 0
Enthusiast ,
Mar 26, 2018

Copied

I only have very few scripts tested in AE and the histogram is not one of them.

If it is possible, I do not know.

May be the histogram data could be passed to an external JSON file and converted outside to a svg using uts RGB colors objects to mix has 'screen' colors mode (possible in SVG css)

Then I do not know AE enough to know if you can import a svg image into a frame by code...

Sorry, I can't help more.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Mar 26, 2018 0
Community Beginner ,
Apr 16, 2018

Copied

Script works, but for those who want histogram for not transparent pixels, modify this script to make selection first (selection without transparent pixels by: Selection->Load->from transparency).

Or use HSB/HSL filter from Win_Optional_Plug-Ins.zip which surely works on selections - above didnt ( it may require more modifications).

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Apr 16, 2018 0
Community Beginner ,
Feb 27, 2019

Copied

Thank you very much for sharing this... I was looking for something similar.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Feb 27, 2019 1
Explorer ,
Sep 16, 2020

Copied

Hey Pedro! Thank you for this wonderful script. Unfortunately it does not work for me on PS 2020 and i can't find out why. Stays just silent.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 16, 2020 0
Sep 16, 2020

Copied

When transferring text from the old forum to the new one, some symbols were removed, in particular [i] and [a].
I fixed it. Try this script.
``````addHistogram(true); // this draws a layer with a coloured 8bit RGB histogram

//addHistogram(false, false, true); //  this draws the Max(, , ) Luminosity RGB histogram (gets the max value of each channel)

//addHistogram(false, true); // this draws a layer with 8bit Lightness channel Lab histogram

//addHistogram(false, false); // this draws a layer with 8bit Luminosity RGB histogram

///////////////////////////////  HISTOGRAM IN LAYER   ///////////////////////////////////

///////////////////////////////////////////////// createProgressWindow

var createProgressWindow = function(title, message, hasCancelButton) {

var win;

if (title == null) title = "Work in progress";

if (message == null) message = "Please wait...";

if (hasCancelButton == null) hasCancelButton = false;

win = new Window("palette", "" + title, undefined);

win.bar = win.add("progressbar", {x: 20, y: 12, width: 300, height: 20 }, 0, 100);

win.stMessage = win.add("statictext", { x: 10, y: 36, width: 320, height: 20 }, "" + message);

win.stMessage.justify = 'center';

if (hasCancelButton) {

win.cancelButton.onClick = function() {

win.close();

throw new Error('User canceled the pre-processing!');

};

}

this.reset = function(message) {

win.bar.value = 0;

win.stMessage.text = message;

return win.update();

};

this.updateProgress = function(perc, message) {

if (perc != null) win.bar.value = perc;

if (message != null) win.stMessage.text = message;

return win.update();

};

this.close = function() {

return win.close();

};

win.center(win.parent);

return win.show();

};

//

// the other layer histograms, if exist, should be invisible so the reading is only on the pixels of the image itself

if (getLayer("RGB histogram")) activeDocument.artLayers.getByName ("RGB histogram").visible = false;

if (getLayer("Lightness Lab histogram")) activeDocument.artLayers.getByName ("Lightness Lab histogram").visible = false;

if (getLayer("Luminosity RGB")) activeDocument.artLayers.getByName ("Luminosity RGB").visible = false;

if (getLayer("Luminosity Max")) activeDocument.artLayers.getByName ("Luminosity Max").visible = false;

//

var layerName = (RGB) ? "RGB histogram" : ((Lab) ? "Lightness Lab histogram" : ((MaxRGB) ? "Luminosity Max" : "Luminosity RGB"));

//

if (!getLayer(layerName)) {

// it works only on RGB images

if (activeDocument.mode == DocumentMode.RGB) {

// if the image is 16bit/channel or more it sets 8bits/channel before read the histogram

if (!activeDocument.bitsPerChannel == BitsPerChannelType.EIGHT) activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;

var wasHereLayer = activeDocument.activeLayer;

var unitsAntes = app.preferences.rulerUnits;

var foregroundPreviousColor = app.foregroundColor;

app.preferences.rulerUnits = Units.PIXELS; // importante

activeDocument.selection.deselect();

//

var hL = activeDocument.histogram;

var hR = activeDocument.channels["Red"].histogram;

var hG = activeDocument.channels["Green"].histogram;

var hB = activeDocument.channels["Blue"].histogram;

// if you want the Luminosity of Lab, export it to Lab, read it, and revert it to RGB

if (Lab) {

activeDocument.changeMode (ChangeMode.LAB);

// read Lightness channel histogram of Lab

var hL = activeDocument.channels["Lightness"].histogram;

// revert to RGB

activeDocument.changeMode (ChangeMode.RGB);

} else {

// read Luminosity composite channel histogram of RGB

var hL = activeDocument.histogram;

}

//

var ww = activeDocument.width.as('px');

var hh = activeDocument.height.as('px');

var totalPixels = ww*hh;

var totalPixels1Col = totalPixels/256;

//

var pBar = new createProgressWindow("Histogram building...", "Please wait", false);

//

activeDocument.activeLayer.name = layerName;

activeDocument.activeLayer.move( activeDocument, ElementPlacement.PLACEATBEGINNING );

activeDocument.activeLayer.blendMode = BlendMode.NORMAL; // blending mode "normal"

activeDocument.activeLayer.opacity = 60; // opacity 60%

//

var hhGraph = 60;

var hY = 400; // base y of graph

var hX = 100; // base x of graph

// base transparent

app.foregroundColor.rgb.red = 0;

app.foregroundColor.rgb.green = 0;

app.foregroundColor.rgb.blue = 0;

//

drawSelectionScreen (hX-2, hY+2, 258+hX, hY-322);

// fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]

app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 40, false);

activeDocument.selection.deselect();

//

var myHist = [];

//

if (RGB) {

for (var a in activeDocument.componentChannels) {

//  criar as 3 cores R, G e B e o graph da cada uma

(a==0) ? app.foregroundColor.rgb.red = 255 : app.foregroundColor.rgb.red = 0;

(a==1) ? app.foregroundColor.rgb.green = 255 : app.foregroundColor.rgb.green = 0;

(a==2) ? app.foregroundColor.rgb.blue = 255 : app.foregroundColor.rgb.blue = 0;

//

if (a==0) myHist = hR;

if (a==1) myHist = hG;

if (a==2) myHist = hB;

//

for ( i = 0; i <= 255; i++ ) {

var col = i+hX;

var YYY = Math.min(Math.floor(myHist[i]*hhGraph/totalPixels1Col), 320);

drawSelectionScreen (col, hY, col+1, hY-YYY);

//

var percent = Math.floor(((i+1)+(a*256))*100/768);

pBar.updateProgress (percent, activeDocument.componentChannels[a].name.toUpperCase() + " Channel " + percent+ " % completed");

}

// fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]

app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);

activeDocument.selection.deselect();

}

} else {

app.foregroundColor.rgb.red = 255;

app.foregroundColor.rgb.green = 255;

app.foregroundColor.rgb.blue = 255;

myHist = hL;

for ( i = 0; i <= 255; i++ ) {

var col = i+hX;

if (MaxRGB) {

var YYY = Math.min(Math.floor(Math.max(hR[i], hG[i], hB[i])*hhGraph/totalPixels1Col), 320);

} else {

var YYY = Math.min(Math.floor(myHist[i]*hhGraph/totalPixels1Col), 320);

}

drawSelectionScreen (col, hY, col+1, hY-YYY);

//

var percent = Math.floor((i+1)*100/256);

pBar.updateProgress (percent, "Luminosity Channel " + percent+ " % completed");

}

// fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]

app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);

activeDocument.selection.deselect();

}

pBar.close();

// activeDocument.activeLayer = wasHereLayer;

app.preferences.rulerUnits = unitsAntes;

app.foregroundColor = foregroundPreviousColor;

} else {

}

} else {

return;

}

function drawSelectionScreen(x1, y1, x2, y2) {

try {

// SelectionType.SELECTEDAREA | DIMINISH | EXTEND | INTERSECT | REPLACE

activeDocument.selection.select([[ x1, y1], [x2, y1], [x2, y2], [x1,y2]], SelectionType.EXTEND, 0, false);

} catch(e) {}

}

function drawLineScreen(x1, y1, x2, y2, width, transparency) {

try {

var desc = new ActionDescriptor();

var lineDesc = new ActionDescriptor();

var startDesc = new ActionDescriptor();

startDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x1 );

startDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y1 );

lineDesc.putObject( charIDToTypeID('Strt'), charIDToTypeID('Pnt '), startDesc );

var endDesc = new ActionDescriptor();

endDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x2 );

endDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y2 );

lineDesc.putObject( charIDToTypeID('End '), charIDToTypeID('Pnt '), endDesc );

lineDesc.putUnitDouble( charIDToTypeID('Wdth'), charIDToTypeID('#Pxl'), width ); //

desc.putObject( charIDToTypeID('Shp '), charIDToTypeID('Ln  '), lineDesc );

desc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Scrn" ) ); // mode: Screen

desc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), transparency ); // [0-100] transparency

desc.putBoolean( charIDToTypeID('AntA'), false ); // important antialias should be false

executeAction( charIDToTypeID('Draw'), desc, DialogModes.NO );

} catch(e) {}

}

//////////////////////////////////

function getLayer(layername) {

var result = false;

for (var a=0; a<activeDocument.artLayers.length ; a++) {

if (String(activeDocument.artLayers[a].name) == layername) {

result = true;

break;

}

}

return result;

}

}

``````

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 16, 2020 1
Explorer ,
Sep 16, 2020

Copied

Hi R-Bin! Thanks for the quick reply. Unfortunately still doesn't work for me. Gives me the spinning cursor for a second or two but that´s it. No histogram layer. Trying this from a pixel layer (copy of the background layer)

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 16, 2020 0
Sep 16, 2020

Copied

It works for me on 21.2.2 (win7)
Check that you have correctly copied the text.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 16, 2020 0
Sep 16, 2020

Copied

It also works on 21.2.3 (Win10)

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 16, 2020 0
Explorer ,
Sep 16, 2020

Copied

Double checked but does not work. Will update from 21.2.0 to 21.2.3. and see what will happen. Thanks again!

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Sep 16, 2020 0
Explorer ,
Oct 09, 2020

Copied

I recently debugged this script with estk and the probem is that the channel names are in english but i use the german version of PS. Of course i can translate that and it works fine then. But is there any way to make this work in all languages?

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Oct 09, 2020 0
Oct 09, 2020

Copied

Use numbers, so 0 or 1 or 2 instead of another RGB or LAB 'colors'.

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Oct 09, 2020 1
Oct 09, 2020

Copied

Das hier sollte sprachunabhängig funktionieren:

``````#target photoshop

addHistogram(true); // this draws a layer with a coloured 8bit RGB histogram
addHistogram(false, false, true); //  this draws the Max([R], [G], [B]) Luminosity RGB histogram (gets the max value of each channel)
addHistogram(false, true); // this draws a layer with 8bit Lightness channel Lab histogram
addHistogram(false, false); // this draws a layer with 8bit Luminosity RGB histogram

///////////////////////////////  HISTOGRAM IN LAYER   ///////////////////////////////////
///////////////////////////////////////////////// createProgressWindow
var createProgressWindow = function(title, message, hasCancelButton) {
var win;
if (title == null) title = "Work in progress";
if (message == null) message = "Please wait...";
if (hasCancelButton == null) hasCancelButton = false;
win = new Window("palette", "" + title, undefined);
win.bar = win.add("progressbar", {x: 20, y: 12, width: 300, height: 20 }, 0, 100);
win.stMessage = win.add("statictext", { x: 10, y: 36, width: 320, height: 20 }, "" + message);
win.stMessage.justify = 'center';
if (hasCancelButton) {
win.cancelButton.onClick = function() {
win.close();
throw new Error('User canceled the pre-processing!');
};
}
this.reset = function(message) {
win.bar.value = 0;
win.stMessage.text = message;
return win.update();
};
this.updateProgress = function(perc, message) {
if (perc != null) win.bar.value = perc;
if (message != null) win.stMessage.text = message;
return win.update();
};
this.close = function() {
return win.close();
};
win.center(win.parent);
return win.show();
};
//
// the other layer histograms, if exist, should be invisible so the reading is only on the pixels of the image itself
if (getLayer("RGB histogram")) activeDocument.artLayers.getByName ("RGB histogram").visible = false;
if (getLayer("Lightness Lab histogram")) activeDocument.artLayers.getByName ("Lightness Lab histogram").visible = false;
if (getLayer("Luminosity RGB")) activeDocument.artLayers.getByName ("Luminosity RGB").visible = false;
if (getLayer("Luminosity Max[R][G][B]")) activeDocument.artLayers.getByName ("Luminosity Max[R][G][B]").visible = false;
//
var layerName = (RGB) ? "RGB histogram" : ((Lab) ? "Lightness Lab histogram" : ((MaxRGB) ? "Luminosity Max[R][G][B]" : "Luminosity RGB"));
//
if (!getLayer(layerName)) {
// it works only on RGB images
if (activeDocument.mode == DocumentMode.RGB) {
// if the image is 16bit/channel or more it sets 8bits/channel before read the histogram
if (!activeDocument.bitsPerChannel == BitsPerChannelType.EIGHT) activeDocument.bitsPerChannel = BitsPerChannelType.EIGHT;
\$.writeln(layerName);
var wasHereLayer = activeDocument.activeLayer;
var unitsAntes = app.preferences.rulerUnits;
var foregroundPreviousColor = app.foregroundColor;
app.preferences.rulerUnits = Units.PIXELS; // importante
activeDocument.selection.deselect();
//
var hL = activeDocument.histogram;
var hR = activeDocument.channels[0].histogram;
var hG = activeDocument.channels[1].histogram;
var hB = activeDocument.channels[2].histogram;
// if you want the Luminosity of Lab, export it to Lab, read it, and revert it to RGB
if (Lab) {
activeDocument.changeMode (ChangeMode.LAB);
// read Lightness channel histogram of Lab
var hL = activeDocument.channels[0].histogram;
// revert to RGB
activeDocument.changeMode (ChangeMode.RGB);
} else {
// read Luminosity composite channel histogram of RGB
var hL = activeDocument.histogram;
}
//
var ww = activeDocument.width.as('px');
var hh = activeDocument.height.as('px');
var totalPixels = ww*hh;
var totalPixels1Col = totalPixels/256;
//
var pBar = new createProgressWindow("Histogram building...", "Please wait", false);
//
activeDocument.activeLayer.name = layerName;
activeDocument.activeLayer.move( activeDocument, ElementPlacement.PLACEATBEGINNING );
activeDocument.activeLayer.blendMode = BlendMode.NORMAL; // blending mode "normal"
activeDocument.activeLayer.opacity = 60; // opacity 60%
//
var hhGraph = 60;
var hY = 400; // base y of graph
var hX = 100; // base x of graph
// base transparent
app.foregroundColor.rgb.red = 0;
app.foregroundColor.rgb.green = 0;
app.foregroundColor.rgb.blue = 0;
//
drawSelectionScreen (hX-2, hY+2, 258+hX, hY-322);
// fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]
app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 40, false);
activeDocument.selection.deselect();
//
var myHist = [];
//
if (RGB) {
for (var a in activeDocument.componentChannels) {
//  criar as 3 cores R, G e B e o graph da cada uma
(a==0) ? app.foregroundColor.rgb.red = 255 : app.foregroundColor.rgb.red = 0;
(a==1) ? app.foregroundColor.rgb.green = 255 : app.foregroundColor.rgb.green = 0;
(a==2) ? app.foregroundColor.rgb.blue = 255 : app.foregroundColor.rgb.blue = 0;
//
if (a==0) myHist = hR;
if (a==1) myHist = hG;
if (a==2) myHist = hB;
//
for ( i = 0; i <= 255; i++ ) {
var col = i+hX;
var YYY = Math.min(Math.floor(myHist[i]*hhGraph/totalPixels1Col), 320);
drawSelectionScreen (col, hY, col+1, hY-YYY);
//
var percent = Math.floor(((i+1)+(a*256))*100/768);
pBar.updateProgress (percent, activeDocument.componentChannels[a].name.toUpperCase() + " Channel " + percent+ " % completed");
}
// fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]
app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);
activeDocument.selection.deselect();
}
} else {
app.foregroundColor.rgb.red = 255;
app.foregroundColor.rgb.green = 255;
app.foregroundColor.rgb.blue = 255;
myHist = hL;
for ( i = 0; i <= 255; i++ ) {
var col = i+hX;
if (MaxRGB) {
var YYY = Math.min(Math.floor(Math.max(hR[i], hG[i], hB[i])*hhGraph/totalPixels1Col), 320);
} else {
var YYY = Math.min(Math.floor(myHist[i]*hhGraph/totalPixels1Col), 320);
}
drawSelectionScreen (col, hY, col+1, hY-YYY);
//
var percent = Math.floor((i+1)*100/256);
pBar.updateProgress (percent, "Luminosity Channel " + percent+ " % completed");
}
// fill (filltype [, mode] [, opacity] [, preserveTransparency])  // filltype: SolidColor  |  mode: ColorBlendMode  |  opacity: [1..100]
app.activeDocument.selection.fill(app.foregroundColor, ColorBlendMode.SCREEN, 100, false);
activeDocument.selection.deselect();
}
pBar.close();
// activeDocument.activeLayer = wasHereLayer;
app.preferences.rulerUnits = unitsAntes;
app.foregroundColor = foregroundPreviousColor;
\$.gc();
} else {
}
} else {
return;
}
function drawSelectionScreen(x1, y1, x2, y2) {
\$.level = 0;
try {
// SelectionType.SELECTEDAREA | DIMINISH | EXTEND | INTERSECT | REPLACE
activeDocument.selection.select([[ x1, y1], [x2, y1], [x2, y2], [x1,y2]], SelectionType.EXTEND, 0, false);
} catch(e) {}
\$.level = 1;
}
function drawLineScreen(x1, y1, x2, y2, width, transparency) {
\$.level = 0;
try {
var desc = new ActionDescriptor();
var lineDesc = new ActionDescriptor();
var startDesc = new ActionDescriptor();
startDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x1 );
startDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y1 );
lineDesc.putObject( charIDToTypeID('Strt'), charIDToTypeID('Pnt '), startDesc );
var endDesc = new ActionDescriptor();
endDesc.putUnitDouble( charIDToTypeID('Hrzn'), charIDToTypeID('#Pxl'), x2 );
endDesc.putUnitDouble( charIDToTypeID('Vrtc'), charIDToTypeID('#Pxl'), y2 );
lineDesc.putObject( charIDToTypeID('End '), charIDToTypeID('Pnt '), endDesc );
lineDesc.putUnitDouble( charIDToTypeID('Wdth'), charIDToTypeID('#Pxl'), width ); //
desc.putObject( charIDToTypeID('Shp '), charIDToTypeID('Ln  '), lineDesc );
desc.putEnumerated( charIDToTypeID( "Md  " ), charIDToTypeID( "BlnM" ), charIDToTypeID( "Scrn" ) ); // mode: Screen
desc.putUnitDouble( charIDToTypeID( "Opct" ), charIDToTypeID( "#Prc" ), transparency ); // [0-100] transparency
desc.putBoolean( charIDToTypeID('AntA'), false ); // important antialias should be false
executeAction( charIDToTypeID('Draw'), desc, DialogModes.NO );
} catch(e) {}
\$.level = 1;
}
//////////////////////////////////
function getLayer(layername) {
var result = false;
for (var a=0; a<activeDocument.artLayers.length ; a++) {
if (String(activeDocument.artLayers[a].name) == layername) {
result = true;
break;
}
}
return result;
}
}  ``````

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Oct 09, 2020 1
Explorer ,
Oct 11, 2020

Copied

Perfekt! Vielen Dank Tom! 🙂

Likes

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Oct 11, 2020 0
LATEST
Oct 11, 2020

Copied