Skip to content

.ai import: an image in a spot ink's Separation space (XC) opens as gray RGB: the ink is lost and its tints draw inverted #6350

Closed

Description

@jmverges

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

  1. Save this as make_xc_ai.py and run python3 make_xc_ai.py .. It writes black-ink-image.ai, a minimal .ai in 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")
  1. 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

  1. ticket-craft commented on Nov 9, 2026

    @ticket-craft

    Possibly related: #6314, #6348 and #3235.

  2. added a commit that references this issue on Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions