Merge pull request #7220 from dotCooCoo/feat/image-indexed-color

Edit Colors: convert embedded images to indexed color
This commit is contained in:
BFlat
2026-11-14 02:40:36 +07:00
committed by GitHub
44 changed files with 770 additions and 23 deletions
+26 -5
View File
@@ -3864,11 +3864,32 @@ with one gray channel, so a PDF writes it in gray.
`edit.colors.saturate` needs `intensity`, a number from -100 to 100 (a number outside the range counts as its nearest
end). Without one, or with `null`, it answers `` missing number `intensity` ``; with a value that is not a number, such as
`"40"`, it answers `` `intensity` must be a number, not "40" ``. Either way it changes nothing.
The `edit.colors.*` commands, `edit.colors.overprintBlack` and `addon.color.filter` answer a `fill`, `stroke`,
`includeImages`, `includePatterns`, `convert`, `remove`, `includeCmyBlacks` or `includeSpotBlacks` that is not true or
false with `` `fill` must be true or false ``, naming the key, a `percentage` that is not a number with
`` `percentage` must be a number ``, and a `mode` that is not a string with `` `mode` must be a string ``. They change
nothing and record no undo step. A null counts as a key left out.
The `edit.colors.*` commands other than `edit.colors.toIndexed`, `edit.colors.overprintBlack` and
`addon.color.filter` answer a `fill`, `stroke`, `includeImages`, `includePatterns`, `convert`, `remove`,
`includeCmyBlacks` or `includeSpotBlacks` that is not true or false with `` `fill` must be true or false ``, naming the
key, a `percentage` that is not a number with `` `percentage` must be a number ``, and a `mode` that is not a string
with `` `mode` must be a string ``. They change nothing and record no undo step. A null counts as a key left out.
`edit.colors.toIndexed` (Edit › Edit Colors › Convert to Indexed Color…) stores each embedded image in the selection (or
`ids`), in groups too, as an indexed-color PNG: a palette of at most 256 RGB colors, with each pixel the index of one.
`reduction` chooses the palette: `selective` (the default), `perceptual`, `adaptive`, `web`, `gray` and `blackWhite`
choose it as a PNG-8 export does; `uniform` takes evenly spaced levels of red, green and blue (2 to 6 levels, the most
whose cube fits in `colors` with one entry left for transparency); `document` takes the colors of the document's
swatches (at most 255). `colors` (2 to 256, default 256) is the most palette entries, the transparent one included;
`uniform` needs at least 9, and `blackWhite` and `document` refuse it. `dither` is `diffusion` (the default), `pattern`,
`noise` or `none`, and `ditherAmount` is 0 to 100 (default 100). Reduction and dither ids are read as a PNG-8 export
reads them, ignoring case. Pixels under half opacity become one transparent entry and the others become opaque in their
own color. Linked images, colorized image fills and the images of color glyphs in outlined type keep their pixels. Each
image that changes becomes a new image, in one undo step for all of them. An image that is already an indexed PNG and
would show the same pixels is left as it is, and no undo step is recorded when no image changes. `notChanged` counts the
locked and hidden objects Select All left out that hold an image that is not an indexed PNG yet. An image of more than
134,217,728 pixels (33,554,432 in the web app) is refused with an error, read from the file's header before any pixel is
decoded, and nothing changes. A value out of range or of the wrong type, such as `"colors": "8"`, is refused with an
error and changes nothing.
```json
{"name":"run_command","arguments":{"command":"edit.colors.toIndexed","params":{"reduction":"adaptive","colors":32,"dither":"pattern"}}}
```
The reply of `recolor.apply` and of every command above except the Blend commands has `notChanged: {locked, hidden}`.
When the selection is exactly what `select.all` takes (in isolation mode, what it takes inside the isolated group), it
+1
View File
@@ -1446,6 +1446,7 @@ Moved from the ROADMAP's "Shipped so far" on 2026-10-10. Update it when a featur
- **Recolor Artwork layout (#3416):** the Edit chip list uses the modal scroll helper and its actual remaining height; the tab's minimum-height space scrolls with the chips. `tests_recolor` covers 5/20/200/400 colors, window resizing, 100/125/150/200% UI scaling, scrolling to and editing the final chip, Preview, Cancel, Confirm and Undo, alongside the existing #1733 drag regressions. Scores and estimates unchanged.
- **Recolor Artwork Edit displays:** buttons beside the Edit tab's wheel show the colors on a smooth color wheel, a segmented color wheel or as color bars ([Edit colors using Recolor Artwork](https://helpx.adobe.com/illustrator/desktop/manage-colors/modify-colors/edit-colors-using-edit-colors-dialog.html)). The segmented wheel draws 24 hues by 5 saturations as solid patches, and its markers move freely as on the smooth wheel. The bars show one solid bar per recolored color in row order: a click selects a bar for the color sliders, and a drag moves its row without changing a color ([Advanced recolor options overview](https://helpx.adobe.com/illustrator/desktop/manage-colors/learn-color-basics/edit-colors-dialog-overview.html)). The dialog opens on the smooth wheel; `display` (`smooth`, `segmented`, `bars`) is the dialog field. `tests_recolor` covers switching, the dialog height, segmented dragging and Brightness, and bar selection, editing, reordering, scrolling, Preview, Cancel and OK. Scores and estimates unchanged.
- **Edit Colors parameters:** `edit.colors.saturate` needs a number `intensity`, the value from -100% to 100% that Saturate takes ([Adjusting colors](https://web.archive.org/web/20230128232631/https://helpx.adobe.com/illustrator/using/adjusting-colors.html)), and answers "missing number `intensity`" without one; a number outside the range counts as its nearest end. A value that is not a number, such as `"40"`, is refused with `` `intensity` must be a number, not "40" ``, as in every command that needs a number (`tests::params::a_malformed_required_number_is_not_reported_as_missing`). `edit.colors.adjustBalance` refuses a channel and `color.harmony` refuses `steps` or `amount` that is not a number; both read `null` as a value left out. `tests::editcolors` and `tests::colorguide` cover them.
- **Convert to Indexed Color:** Edit › Edit Colors › Convert to Indexed Color… (`edit.colors.toIndexed`) stores the embedded images in the selection as indexed-color PNGs of at most 256 colors. The palette is chosen as for a PNG-8 export, as evenly spaced levels of red, green and blue, or from the document's swatches, with diffusion, pattern or noise dithering; pixels under half opacity become transparent. The dialog previews live, and OK is one undo step. This is VectorCraft's own command and counts toward no score. `tests::editcolors` and `encode::tests_palette` cover it. Scores and estimates unchanged.
- **Working RGB numeric controls:** the Color panel and Color Picker read RGB, HSB, hex and Web Safe RGB values in the active working RGB space. Editing one RGB channel preserves the other native channels, including colors outside display sRGB. Regressions cover sRGB, Display P3, Wide Gamut RGB and ProPhoto RGB, picker initialization, native numeric round trips, and a slider click with one Undo step. Scores and estimates unchanged.
- **Pasting into hex color fields:** in the hex fields of the Color Picker, Swatch Options, Recolor Artwork, the Color panel, Document Setup, Duotone, Color Themes and Perspective Grid, a click or keyboard focus selects the digits. A pasted code of six digits, with or without `#`, replaces them wherever the caret is. A pasted code of three digits also replaces them, unless the paste holds only those digits and exactly three digits stay; those digits then edit the text in place. A press on another field commits the text as Tab and Enter do. As VectorCraft's own rule, a paste that is not a color leaves the field as it was. Tests: `a_hex_code_pasted_into_the_hex_field_replaces_its_digits` in `crates/ui-egui/src/dialogs/tests.rs`, `define_grid_takes_a_three_digit_color` in `crates/ui-egui/src/dialogs/tests_perspective.rs` and `a_paste_into_a_hex_field_replaces_or_edits_its_digits` in `crates/ui-egui/src/tests/numfields.rs`.
- **Color Picker layout (#2008):** a centered draggable header, equal-width actions above aligned HSB/RGB/Hex and Lab/CMYK fields, compact field and slider, and warnings below the preview. No horizontal scrolling; narrow windows stack the sections with vertical scrolling. Tests in `dialogs/color_picker.rs` cover actual pointer/key input, typed values before OK/Enter, Cancel/Escape rollback, one Undo step, mode-size stability, warnings and layout at two UI scales. The screen sampler sits above the field and the upstream two-grid Tab order is retained. AccessKit regressions check the action names and each channel slider's displayed value, units and range. German and enlarged English UI renders were reviewed locally; no reference images are shipped. This is a layout improvement, with no change to scores or remaining-hour estimates.