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

Script to find colour in "black & white" jpgs

Participant ,
Oct 08, 2023 Oct 08, 2023

Copy link to clipboard

Copied

Hi,

 

I regularly want to sort a folder of JPGs that visually look black and white but may contain colour pixels. Is there a Bridge script available that can check each JPG and move any JPGs that have any colour pixels to another folder.

 

My scripting skills are close to zero but I have been able to customise existing scripts to my own needs if provided with a script that is similar to my needs. Unfortunately, searching the Photoshop and Bridge communities I haven’t been able to find a script that is likely to help.

 

Thanks in advance, any help that can be provided will be much appreciated.

 

Cheers 

 

Leo

TOPICS
How to , Scripting

Views

1.2K

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

correct answers 1 Correct answer

Community Expert , Oct 10, 2023 Oct 10, 2023

@leol30 

 

EDIT: Script updated to version 1.1 where files that fail the test for neutrality are moved to a "Rejected" folder.

 

This Photoshop script will process the root/top-level of an input folder for supported files and will log files to the desktop in a text file that have a Standard Deviation value for the sum of the a+b channels that is greater than 0.00 (0.00 being fully neutral).

 
You can adjust the tolerance/threshold for neutral values from the default 0.00 by adjusting the follow
...

Votes

Translate

Translate
Community Expert ,
Oct 08, 2023 Oct 08, 2023

Copy link to clipboard

Copied

@leol30 

 

I don’t hold much hope... 

 

I presume that these are neutral channel RGB grayscale images (R=G=B), not true grayscale mode.

 

The JPEG compression algorithm will likely create colour pixel artefacts which are not neutral.

 

In theory, it would be possible to create a script that would open the images in Photoshop and say convert to Lab colour mode, where it is easier to evaluate the histogram of the "a" and "b" channels for values which are not equal to zero, then apply a Bridge rating or label or other metadata to "mark" the file. Some sort of threshold value could be applied to filter our false positives that may contain a small amount of rogue coloured pixels... But all that is a lot of work!

 

It would be much easier to simply process an entire folder of images forcing them to be neutral, however, the JPEG format may create rogue pixels anyway!

 

You could upload a sample image that both meets and doesn't meet the criteria of being "coloured".

 

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 ,
Oct 09, 2023 Oct 09, 2023

Copy link to clipboard

Copied

Stephen, thanks for your help. The images have different color profiles. I can remove grayscale images from the folder using the Bridge Color Mode filter. The method I use to find images that have coloured pixels is Open each image, turn up the Saturation to 100 and Save using a Photoshop action. I can then visually see the images that have colour pixels in them and move them to another folder. I thought there might be a "function" that could be used in a script to interrogate each file to see if any pixels were coloured rather than black, white or shades of grey. From what you've said I guess I'm asking for too much. Once again thanks for replying. I have uploaded four images so that you can see what I’m trying to explain. A picture is worth a thousand words! Two of images look black and white until the Saturation is turned up to 100.

 

 

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 ,
Oct 09, 2023 Oct 09, 2023

Copy link to clipboard

Copied

Inspecting a file for color pixels probably could be done, but it would be very difficult. It's beyond my knowledge.

An easier, but not 100% reliable, method would be to look at the metadata. This is not reliable because you have to count on prior software processes to correctly write color metadata and that doesn't always happen. Having said that, if your files have been processed that same way, then the metadata should be consistent, at least consistent enough to locate most of the color images. You could then manually test the remainder.

 

Here's one easy clue: your sample images are RGB

gregreser_3-1696865763971.png

 

You can also see this in the Filter panel, but it shows the difficulty in relying on metadata.

rocks is sRGB

gregreser_1-1696865007829.png

 

water is untagged (color images can also be untagged, unfortunately)

gregreser_2-1696865087686.png

 

Have a look at the greyscale version of water.jpg and see what the Filter and File Properties say. Your file metadata might be consistent enough to identify the not-really-b&w images just using standard Bridge tools.

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 ,
Oct 09, 2023 Oct 09, 2023

Copy link to clipboard

Copied

quote

Inspecting a file for color pixels probably could be done, but it would be very difficult. It's beyond my knowledge.


By @gregreser

 

I would use a Bridge or Photoshop script to open each image into Photoshop, then check via Lab histogram the A or B channels. RGB and CMYK modes mix both colour and luminosity, however in Lab mode, the Lightness is cleanly separated from the colour component, so the L channel can be ignored. Then all one has to do is determine if the A or B channels have a median value of 128 (neutral) or a Standard Deviation value that was not equal to 0 (zero). The A and B channel Mean, Median and Std. Dev. values can all be used to determine the overall deviance from neutral. Obviously, smaller variations may be "rounded out" with methods such as Mean.

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 ,
Oct 09, 2023 Oct 09, 2023

Copy link to clipboard

Copied

quote

I thought there might be a "function" that could be used in a script to interrogate each file to see if any pixels were coloured rather than black, white or shades of grey.

 

Not that I am aware of in Bridge.

 

In Photoshop, as I previously described one can use scripting to evaluate the Lab colour mode histogram for the A and B channels. This takes time, as each image needs to be opened, converted to Lab mode, then have the A and B channel histograms evaluated by the script. It is certainly possible, but is it really worth doing?

 

 

quote

From what you've said I guess I'm asking for too much. Once again thanks for replying. I have uploaded four images so that you can see what I’m trying to explain. A picture is worth a thousand words! Two of images look black and white until the Saturation is turned up to 100.

 


By @leol30

 

I never said you were asking for too much – but it is a lot of work!

 

The main problem is that you are working with JPEG files:

 

1) Resaving such files can introduce further degradation, whether minor or not.

 

2) The lossy compression can introduce non-neutral artefacts:

 

rocks saturation 100.jpg

 

In your rock image, the JPEG 8x8 pixel blocking can clearly be seen when you pump up the saturation. I would consider this a "false positive" as the image probably was/is neutral apart from the JPEG damage.

 

This is different to your water image, where it looks like the issue was with the original conversion from colour to gray:

 

water saturation 100.jpg

 

There are some 8x8 blocks in the background which were introduced by the JPEG save, however, the entire water looks like an error in conversion as it is uniformly -2 in the B channel of Lab, so this would be a "true positive" result in my opinion.

 

My question is, why is your image processing not creating a true neutral before saving to JPEG (presuming that it isn't just a coincidence that the water wasn't neutral but slightly blue)?

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 ,
Oct 10, 2023 Oct 10, 2023

Copy link to clipboard

Copied

My question is, why is your image processing not creating a true neutral before saving to JPEG (presuming that it isn't just a coincidence that the water wasn't neutral but slightly blue)?


By @Stephen_A_Marsh

 

I'm checking over 400 images each week that have been saved by over 400 different photographers. It's for a black and white photography group and the rule states that the images submitted must be "in black, white, shades of gray, and no other color" i.e. desaturated. 

 

Thanks everyone for the suggestions. I need to digest the suggestions to see whether I can get my head round the options. In the meantime, I'll carry on using my "manual" method of turning up the saturation and sorting them visually by eye. Your help and advice is most appreciated. Thanks again.

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
LEGEND ,
Oct 10, 2023 Oct 10, 2023

Copy link to clipboard

Copied

This could probably be done using ImageJ instead of Adobe software.

https://imagej.net/

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 ,
Oct 10, 2023 Oct 10, 2023

Copy link to clipboard

Copied

@leol30 

 

EDIT: Script updated to version 1.1 where files that fail the test for neutrality are moved to a "Rejected" folder.

 

This Photoshop script will process the root/top-level of an input folder for supported files and will log files to the desktop in a text file that have a Standard Deviation value for the sum of the a+b channels that is greater than 0.00 (0.00 being fully neutral).

 
You can adjust the tolerance/threshold for neutral values from the default 0.00 by adjusting the following line of code:
 
if (theValue > 0.00) {
 
This script is more a proof of concept than anything, but it may be useful if you can come up with a suitable Std. Dev. value that accounts for the colour artefacts introduced by JPEG compression. The Mean or Median values of combined or single a & b channels could also be used instead.

 

If this does prove useful I am happy to make changes to the script.

 

P.S. I am more comfortable scripting Photoshop than Bridge, which is why this is a Photoshop script, despite this topic being on in the Bridge forum.

 

Here is the full script for Photoshop:

 

/*
Batch Log Non-Neutral B&W Files from Input Folder.jsx
https://community.adobe.com/t5/bridge-discussions/script-to-find-colour-in-quot-black-amp-white-quot-jpgs/td-p/14141472
v1.1 - 11th October 2023, Stephen Marsh

Info:
This Photoshop script will process the root/top-level of an input folder
for supported files and will log files to the desktop in a text file
that have a Standard Deviation value for the sum of the a+b channels
that is greater than 0.00 (0.00 being fully neutral). A new folder
named "Rejected" will be created in the input folder and documents
which fail will be moved to this folder.
*/

#target photoshop

if (app.documents.length === 0) {

    // Select the folder containing the files
    var inputFolder = Folder.selectDialog("Select the input folder", "");

    // Add or remove supported file extensions as required
    var inputFiles = inputFolder.getFiles(/\.(jpg|jpeg|tif|tiff|psd|psb|png|bmp|webp|tga)$/i);
    inputFiles.sort();

    // Set the input file counter
    var inputFileCounter = 0;

    // Set the failed file counter
    var failedCounter = 0;

    // Initial log file entries
    var dateTime = new Date().toLocaleString();
    var logFile = new File("~/Desktop/Neutral File Evaluation.log");
    if (logFile.exists)
        logFile.remove();
    var os = $.os.toLowerCase().indexOf("mac") >= 0 ? "mac" : "windows";
    if (os === "mac") {
        var logFileLF = "Unix";
    } else {
        logFileLF = "Windows";
    }
    logFile.open("w");
    logFile.encoding = "UTF-8";
    logFile.lineFeed = logFileLF;
    logFile.writeln(dateTime);
    logFile.writeln(inputFolder.fsName + "/" + "Rejects" + "/");
    logFile.close();

    // Process the files
    for (var i = 0; i < inputFiles.length; i++) {
        open(inputFiles[i]);
        
        // Convert to Lab mode
        activeDocument.changeMode(ChangeMode.LAB);
        
        // Histogram evaluation
        var aCha = theHistProps(activeDocument.channels[1].histogram);
        var bCha = theHistProps(activeDocument.channels[2].histogram);
        // theMean = [0] | theMedian = [1] | theStandDev = [2]
        var theValue = (((aCha[2] + bCha[2]) / 2).toFixed(2));
        
        /* Change neutral target value as required */
        if (theValue > 0.00) {

            // Rejected files variables and folder
            var theDoc = activeDocument;
            var theName = theDoc.name;
            var theFolder = Folder(theDoc.path + "/" + "Rejects");
            if (!theFolder.exists) {
                theFolder.create()
            }

            try {
                writeFailedLogEntry();
                failedCounter++;
                
                // Copy the rejected files
                File(theDoc.fullName).copy(theFolder + "/" + theName);
                
                // Remove the original files
                theDoc.fullName.remove();

            } catch (e) {}
            // Close without saving
            activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        } else {
            // Close without saving
            activeDocument.close(SaveOptions.DONOTSAVECHANGES);
        }
        inputFileCounter++;
    }

    // End of script notification
    alert(inputFileCounter + " files processed:" + "\r" + failedCounter + " files failed");

} else {
    alert('No documents should be open when running this script!');
}


///// FUNCTIONS /////

function writeFailedLogEntry() {
    var os = $.os.toLowerCase().indexOf("mac") >= 0 ? "mac" : "windows";
    if (os === "mac") {
        var logFileLF = "Unix";
    } else {
        logFileLF = "Windows";
    }
    logFile.open("a");
    logFile.encoding = "UTF-8";
    logFile.lineFeed = logFileLF;
    logFile.writeln("FAILED = (" + theValue + ") " + activeDocument.name + "\r");
    logFile.close();
}

function theHistProps(theHist) {
    /* Based on https://community.adobe.com/t5/photoshop/how-to-get-the-histogram-s-std-dev/td-p/9875041 */
    // get total number;
    var thePixels = 0;
    for (var m = 0; m < theHist.length; m++) {
        thePixels = thePixels + theHist[m];
    }
    // get mean and median
    var theMean = 0;
    var aTotal = 0;
    var check = false;
    for (var n = 0; n < theHist.length; n++) {
        theMean = theMean + (n * theHist[n] / thePixels);
        aTotal = aTotal + theHist[n];
        if (aTotal >= thePixels / 2 && check === false) {
            theMedian = n;
            check = true;
        }
    }
    // get standard deviation
    var theStandDev = 0;
    for (var o = 0; o < theHist.length; o++) {
        theStandDev = theStandDev + (Math.pow((o - theMean), 2) * theHist[o]);
    }
    theStandDev = Math.sqrt(theStandDev / thePixels);
    // Return the properties: theMean = [0] | theMedian = [1] | theStandDev = [2]
    return ([theMean, theMedian, theStandDev]);
}

 

  1. Copy the code text to the clipboard
  2. Open a new blank file in a plain-text editor (not in a word processor)
  3. Paste the code in
  4. Save as a plain text format file – .txt
  5. Rename the saved file extension from .txt to .jsx
  6. Install or browse to the .jsx file to run (see below)

https://prepression.blogspot.com/2017/11/downloading-and-installing-adobe-scripts.html

 

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

@Stephen_A_Marsh 

 

I changed the tolerance/threshold for neutral value to 0.00 and the script found the obvious coloured images and also gave me three more that I would have missed on visual inspection. Thanks very much for your support, JPEG and scripting knowledge. WOW! Thank you very much for the scriptMuch appreciated.

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

You're welcome. I started with zero, however, I thought that might be too strict. Glad it worked for you! Are there any improvements or suggestions that would make things better?

 

If so, let me know... Otherwise if you could mark the post with the script as a correct answer that would be great.

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

quote

Are there any improvements or suggestions that would make things better?

 

If so, let me know... 


By @Stephen_A_Marsh


Thanks for the offer. I'm really pleased with the generated text file list so that I can move the files myself but if it is possible to move the files to another folder that would be "the icing on the cake".

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

quoteThanks for the offer. I'm really pleased with the generated text file list so that I can move the files myself but if it is possible to move the files to another folder that would be "the icing on the cake".

By @leol30

 

Would you like the script to make a "Rejects" folder in the source folder and move the files that fail there?

 

(I was thinking of automatically opening the failed files in Photoshop)

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

quote

 

Would you like the script to make a "Rejects" folder in the source folder and move the files that fail there?

 

By @Stephen_A_Marsh

 

That would be excellent. Moving them rather than opening them in PS.

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

@leol30 

 

I have updated the script to a 1.1 version.

 

Please note: JavaScript can't move the files, but it can copy them and then permanently delete the originals. This isn't semantics, I need to make it clear to you what is happening (file dates will change) as there is potential for the original files to be lost if something goes wrong and you don't have a backup of them.

 

It might be possible to use a platform-specific OS script call to truly move the files rather than copy them, however, I don't recall seeing that before (perhaps a rainy day project).

 

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

quote

 

I have updated the script to a 1.1 version.

 


By @Stephen_A_Marsh

 

Stephen, It works a treat. Once again, thanks for your help and the script that does what I was asking for. A real time saver me. Cheers Leo

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 ,
Oct 11, 2023 Oct 11, 2023

Copy link to clipboard

Copied

LATEST

@Stephen_A_Marsh really nice work!

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