如何使用Python读取Photoshop的.act格式文件?
I spent ages searching everywhere for a way to parse Photoshop palette files (both .aco and .act formats) and couldn't find a solid, ready-to-use solution. So I rolled up my sleeves and built my own implementation—here's what I came up with, in case you're stuck too.
Parsing .act Files (The Simple One)
The .act format is pretty straightforward—it's a binary file that holds up to 256 RGB color triplets, plus an optional transparency index. Here's a Python script to read it:
def read_act_palette(file_path): try: with open(file_path, 'rb') as f: # First 768 bytes = 256 RGB colors (3 bytes per color) rgb_bytes = f.read(768) palette = [] # Iterate through each 3-byte RGB triplet for idx in range(0, len(rgb_bytes), 3): r = rgb_bytes[idx] g = rgb_bytes[idx + 1] b = rgb_bytes[idx + 2] palette.append((r, g, b)) # Check for optional transparency index (1 extra byte) transparency_byte = f.read(1) transparency_idx = ord(transparency_byte) if transparency_byte else None return palette, transparency_idx except FileNotFoundError: print(f"Error: File {file_path} not found.") return None, None
How this works:
- It reads the first 768 bytes directly into RGB values (each channel is an 8-bit integer, 0-255).
- If the file has an extra byte at the end, that's the index of the color that should be treated as transparent.
Parsing .aco Files (The More Complex Format)
.aco files have two versions—version 1 is basic (stores RGB/CMYK/HSB values), while version 2 adds support for named colors and more color spaces. Below is a parser for version 1, which covers most standard use cases:
def read_aco_palette(file_path): palette = [] try: with open(file_path, 'rb') as f: # Read version (2 bytes, big-endian) and color count (2 bytes) version = int.from_bytes(f.read(2), byteorder='big') color_count = int.from_bytes(f.read(2), byteorder='big') if version == 1: for _ in range(color_count): # Color space identifier: 0 = RGB, 1 = HSB, 2 = CMYK, etc. color_space = int.from_bytes(f.read(2), byteorder='big') # Read 4 color components (each 2 bytes, big-endian) comp1 = int.from_bytes(f.read(2), byteorder='big') comp2 = int.from_bytes(f.read(2), byteorder='big') comp3 = int.from_bytes(f.read(2), byteorder='big') comp4 = int.from_bytes(f.read(2), byteorder='big') # Handle RGB color space (most common) if color_space == 0: # Convert 16-bit values (0-65535) to 8-bit (0-255) r = comp1 // 256 g = comp2 // 256 b = comp3 // 256 palette.append((r, g, b)) # Add handlers for HSB/CMYK if you need them! # Version 2 parsing can be added to support color names, but this covers basics except Exception as e: print(f"Error reading .aco file: {str(e)}") return None return palette
Key notes for .aco:
- The file uses big-endian byte ordering, so we specify that when converting bytes to integers.
- RGB values are stored as 16-bit integers, so we divide by 256 to get the standard 8-bit range.
- For version 2, you'd need to parse additional Unicode strings for color names—feel free to expand the code if you need that functionality!
Quick Tips for Use
- Always add error handling (like the
try-exceptblocks I included) to deal with corrupted files or missing paths. - Test with palettes you export directly from Photoshop to make sure the parser behaves as expected.
- If you need to write palettes back to these formats, the logic is similar—just reverse the byte-writing steps.
内容的提问来源于stack exchange,提问作者DayDreamer

