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

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

Views

5.6K

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

Valorous Hero , 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.
var d
...

Votes

Translate

Translate
Adobe
LEGEND ,
Apr 26, 2020 Apr 26, 2020

Copy link to clipboard

Copied

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
Valorous Hero ,
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.

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
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...

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 ,
May 03, 2022 May 03, 2022

Copy link to clipboard

Copied

LATEST

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
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

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
Valorous Hero ,
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.

 

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
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. 

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
Valorous Hero ,
Jul 29, 2021 Jul 29, 2021

Copy link to clipboard

Copied

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++) {

 

 

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