Welcome Dialog

Welcome to the Community!

We have a brand new look! Take a tour with us and explore the latest updates on Adobe Support Community.


How do I export the color table (.act file) using a script?

New Here ,
Apr 26, 2020 Apr 26, 2020

Copy link to clipboard

Copied

Hi!

I'm trying to automate some of the work I am doing by scripting in Photoshop. I have a bunch of PNG files, where I need to find out which colors each and every image consists of (RBG values). I thought I could do something like this (for each and every one):

1) Open the file

2) Convert the file to Indexed color

3) Save the Color Table (as an .act file)

4) Have a Python script post-process the .act files and printout the RGB values into another file, one for each picture.

I have steps 1, 2 and 4 under control and tested. But step #3 I cannot for my life understand how to do, or even if it is possible. I've looked at the JavaScript reference guide provided by Adobe, but I cannot find any suitable method, constant, object or anything that would help me here.

 

So, my quesiton is... Is there a way for me to extract the Color Table by using a script?

(If you have any other ideas on how one could achieve this in a better way that would be awesome. The end goal is, as stated, to get the RGB colors from (many) PNG files (separated per file)).

TOPICS
Actions and scripting, How to

Views

2.1K

Likes

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

Adobe Community Professional , Apr 26, 2020 Apr 26, 2020
Adobe often has glitches or unfinished features. The code to load from the act file is like this and it works. var d = new ActionDescriptor(); var r = new ActionReference(); r.putProperty(stringIDToTypeID("color"), stringIDToTypeID("colorTable")); d.putReference(stringIDToTypeID("null"), r); d.putPath(stringIDToTypeID("to"), new File("C:/1/aaa.act")); executeAction(stringIDToTypeID("set"), d, DialogModes.NO); The code for exporting to the act file should be like this, but it does not work. va...

Likes

Translate

Translate
Adobe Community Professional ,
Apr 26, 2020 Apr 26, 2020

Copy link to clipboard

Copied

Likes

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
Adobe Community Professional ,
Apr 26, 2020 Apr 26, 2020

Copy link to clipboard

Copied

Adobe often has glitches or unfinished features.

The code to load from the act file is like this and it works.
var d = new ActionDescriptor();
var r = new ActionReference();
r.putProperty(stringIDToTypeID("color"), stringIDToTypeID("colorTable"));
d.putReference(stringIDToTypeID("null"), r);
d.putPath(stringIDToTypeID("to"), new File("C:/1/aaa.act"));
executeAction(stringIDToTypeID("set"), d, DialogModes.NO);

The code for exporting to the act file should be like this, but it does not work.
var d = new ActionDescriptor();
d.putPath(stringIDToTypeID("null"), new File("C:/1/aaa.act"));
var r = new ActionReference();
r.putProperty(stringIDToTypeID("color"), stringIDToTypeID("colorTable"));
d.putReference(stringIDToTypeID("to"), r);
executeAction(stringIDToTypeID("set"), d, DialogModes.NO);
 

To solve your problem, you can use simplified parsing of the psd file to extract data directly.
try {
var act_file = new File("C:/1/aaa.act"); // your act-file here

var tmp_file = new File(Folder.temp.fsName + "/" + "~tmp.psd");

var d = new ActionDescriptor();
var d1 = new ActionDescriptor();
d1.putBoolean(stringIDToTypeID("maximizeCompatibility"), false);
d.putObject(stringIDToTypeID("as"), stringIDToTypeID("photoshop35Format"), d1);
d.putPath(stringIDToTypeID("in"), tmp_file);
d.putBoolean(stringIDToTypeID("copy"), true);
d.putBoolean(stringIDToTypeID("spot"), false);
d.putBoolean(stringIDToTypeID("alphaChannels"), false);
d.putBoolean(stringIDToTypeID("layers"), false);
d.putBoolean(stringIDToTypeID("embedProfiles"), false);
d.putBoolean(stringIDToTypeID("annotType"), false);
executeAction(stringIDToTypeID("save"), d, DialogModes.NO);

var s = "";

if (!tmp_file.open("r")) { throw("tmp file open error"); }
tmp_file.encoding = "BINARY";

tmp_file.seek(25, 0);

s = tmp_file.read(1);

if (s.charCodeAt(0) != 2) { throw("wrong color mode"); }

s = tmp_file.read(4);

var len = s.charCodeAt(0)<<24 | s.charCodeAt(1)<<16 | s.charCodeAt(2)<<8 | s.charCodeAt(3);

if (len != 0x300) { throw("wrong color len"); }

var table = tmp_file.read(len);

s = tmp_file.read(4);

var len = s.charCodeAt(0)<<24 | s.charCodeAt(1)<<16 | s.charCodeAt(2)<<8 | s.charCodeAt(3);

var data = tmp_file.read(len);

tmp_file.close();
tmp_file.remove();

var color_cnt = 256;
var transp_idx = 0xFFFF;

var n = data.indexOf("8BIM"+ String.fromCharCode(0x04,0x16,0,0,0,0,0,2));

if (n >= 0)
    {
    color_cnt = data.charCodeAt(n+12)<<8 | data.charCodeAt(n+13);
    //alert(color_cnt)
    }

var n = data.indexOf("8BIM"+ String.fromCharCode(0x04,0x17,0,0,0,0,0,2));

if (n >= 0)
    {
    transp_idx = data.charCodeAt(n+12)<<8 | data.charCodeAt(n+13);
    //alert(transp_idx)
    }

if (!act_file.open("w")) { throw("open error"); }
act_file.encoding = "BINARY";

for (var i = 0; i < 256; i++) 
    act_file.write(String.fromCharCode(table.charCodeAt(i), table.charCodeAt(256+i), table.charCodeAt(512+i)));

if (color_cnt != 256 || transp_idx != 0xFFFF) 
    act_file.write(String.fromCharCode(color_cnt>>8, color_cnt&0xFF, transp_idx>>8, transp_idx&0xFF));


if (act_file.error) { throw(act_file.error); }
    
act_file.close();

alert("done");
} 
catch(e) { alert(e); }
 
Check it out. It works.

Likes

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
New Here ,
Apr 27, 2020 Apr 27, 2020

Copy link to clipboard

Copied

Wow, that's awesome. It really does work. The only part left now is to make that snippet of code work on all open documents (there will be a bunch of PNGs I want to iretate over and do the same for each and every one of them).

Thank you, I would never have solved this myself. I was about to resort to manually saving the .act files myself by going through the dialogue boxes...

Likes

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
New Here ,
Jul 26, 2021 Jul 26, 2021

Copy link to clipboard

Copied

Hi there,

I'm using a script to add colour chips to an image –credit to Wolff (Script to Create Colour Chip Layers in Photoshop)– but it's only working on my one machine. As seen in the screenshots, all other machines end up with a grey layer in place of the colour chips layer.

I've tried on a range of machines –between Mac and PC, Photoshop 2020 and 2021– and I cannot work out why it wouldn't work on other machines.

The script (saved as a txt for attaching) and screenshots are attached for reference.

Any one have any ideas?

Thanks,

Ben

Likes

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
Adobe Community Professional ,
Jul 29, 2021 Jul 29, 2021

Copy link to clipboard

Copied

Comment out the line

tempFile.remove ();

 

and provide here the file "~ tmp.psd" from the temporary folder on the problem machine, which (file) is formed after the script is run.

 

Likes

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
New Here ,
Jul 29, 2021 Jul 29, 2021

Copy link to clipboard

Copied

Thanks for looking into this, r-bin. The "~ tmp.psd" file is attached. 

Likes

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
Adobe Community Professional ,
Jul 29, 2021 Jul 29, 2021

Copy link to clipboard

Copied

LATEST

And what exactly is your problem?

The attached file is correct.

For debugging, you can insert after the loop

for (var i = 0; i < colorCount; i++) {
    chipColors.push([table.charCodeAt(i), table.charCodeAt(256+i), table.charCodeAt(512+i)]);
}

 

the line

alert(chipColors.toSource())

and show the result on the screenshot.

 

Note, because your file has 256 colors in the table, then for the correct display of the result your file must be at least 64 + 256 * (128 + 16) = 36928 pixels wide.

 

You can shorten the loop for debugging by replacing

// Draw chips
for (var i = 0; i < chipColors.length; i++) {

 

with

// Draw chips
for (var i = 0; i < 8; i++) {

 

 

Likes

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