Repository navigation
Description
What happens
In a .ai's editing data, an image whose color space is one spot ink, set by n [c m y k /DeviceCMYK (name) /Separation] XC (or an RGB alternate) before its XI, opens as a gray RGB image: its samples, which are the ink's tints (255 at 100 %), are read as gray levels. So:
- The tints draw inverted. No ink draws black, and 100 % of a dark ink draws white. A 3 × 1 image of tints 0, 50 % and 100 % in "Black Ink" renders black, mid gray and white.
- The ink is lost: no spot swatch, no plate in Separations Preview, nothing in
recolor.colors.
XC is on the list of operators the reader ignores. It was added there in #4179 for /DeviceGray XC after a linked image's file name.
I hit this in our own garment files, which have images in screen-print inks (a white underbase, a black ink) with an alpha channel; used locally, not attached. Their PDF part has the same images as Separation images with a soft mask (#6314, #6347).
Steps to reproduce
- Save this as
make_xc_ai.pyand runpython3 make_xc_ai.py .. It writesblack-ink-image.ai, a minimal.aiin PostScript form whose one image is 3 × 1 tints of "Black Ink". Written by hand.
# Writes a minimal .ai in PostScript form (its own editing data) with one 3 x 1 image whose samples
# are a spot ink's tints (0, 50 %, 100 %), its color space set by XC. Written by hand.
import sys
def ai(xc, name):
data = bytes([0, 128, 255])
head = ("%!PS-Adobe-3.0\n%%Creator: hand-written\n%AI5_FileFormat 14.0\n%AI3_Cropmarks: 0 0 200 100\n"
"%%EndComments\n%%BeginProlog\n%%EndProlog\n%%BeginSetup\n%%EndSetup\n"
"%AI5_BeginLayer\n1 1 1 1 0 0 1 0 79 128 255 0 50 0 Lb\n(L) Ln\n%AI5_File:\n%AI5_BeginRaster\n() 1 XG\n"
f"{xc} XC\n[ 60 0 0 60 10 90 ] 3 1 0 Xh\n[ 60 0 0 60 10 90 ] 0 0 3 1 3 1 8 1 0 0 1 0 4 4 0 0\n"
f"%%BeginData: {len(data) + 3}\rXI\n").encode()
tail = (b"%%EndData\r\nXH\r\n%AI5_EndRaster\r\nN\r\nLB\r\n%AI5_EndLayer--\r\n"
b"%%PageTrailer\ngsave annotatepage grestore showpage\n%%Trailer\n%%EOF\n")
open(name, "wb").write(head + data + tail)
out = sys.argv[1]
ai("1 [0 0 0 1 /DeviceCMYK (Black Ink) /Separation]", f"{out}/black-ink-image.ai")- Open it and export it:
vectorcraft-cli run --in black-ink-image.ai --cmd select.all --cmd image.info --cmd recolor.colors --cmd view.separationsPreview --params '{"on":true}' --export out.png --ppi 72
image.info gives "colorMode":"RGB", recolor.colors gives "colors":[], the plates are Cyan, Magenta, Yellow and Black, and out.png shows the three pixels as black, gray and white.
Expected
A grayscale image of the tints, black at 100 %, colorized by the ink's spot swatch, as #6347 opens a Separation image from a PDF. The alpha channel becomes the opacity mask, as the reader already does for other images.
Where it comes from
crates/eps/src/import/ai/read/types.rs: XC in IGNORED. crates/eps/src/import/ai/read/art.rs, image_from: a one-channel image's samples are read as gray.
Version
VectorCraft 0.23.0, vectorcraft-cli from the Linux x86_64 release tarball.
I have a fix ready; PR to follow.
Activity
ticket-craft commentedon Nov 9, 2026
Possibly related: #6314, #6348 and #3235.
.ai import: images in a spot ink's Separation space keep their ink (#…
Merge pull request #6379 from jmverges/fix/ai-separation-rasters