GNOME Bugzilla – Bug 66258
Colors that should not be modified during RGB->Indexed conversion
Last modified: 2018-05-24 10:38:24 UTC
It would be nice to have a way to select one or several colors that should not be averaged or otherwise modified when generating an "optimal palette" for the RGB->Indexed conversion. For example, if I select black (#000000) and white (#ffffff) among the colors to be preserved and then I convert an RGB image to indexed mode using the option "Generate Optimal Palette", then these colors will not be averaged with another color when creating the new palette. So if the image contains some areas that are black or white (and no dithering is used) then these areas will keep the exact same color. If the image did not contain any black or white pixels, then the palette will be generated as before, without any constraints. One way to present that in the user interface would be to add an option below the existing "Generate Optimal Palette" option that would labeled as "Generate Optimal Palette and Preserve Colors from [palettes menu]" (Any ideas for a better wording?). If the image contains any color from the selected palette, they would first be copied to the new palette. After that, the other colors are allocated (up to the maximum allowed) using the same algorithm as before. So the user could for example select the web-safe color palette and any parts of the image containing one of these colors would still be web-safe after the conversion to indexed mode (but this is different from the "Use Custom Palette" option because the other colors could still be allocated freely). Another example would be to create a palette containing some "important" colors (spot colors for a corporate log or colors used for chroma keying in some applications); these colors would be preserved in the indexed image. This enhancement would be another way (slightly more complicated) to solve the problem described in bug #66257. I consider the solution described in #66257 as a quick fix for the bug (maybe suitable for 1.2.x) and this one as an enhancement that provides a better solution (for 1.3.x or later).
This has gotten some thought over the last few years but I don't think it's as easy as your solution. Well, it /is/ as easy as your solution but you end up with two palette sections that don't know about each other so the 'optimal' half is likely to end up making choices that are very close to the 'locked-down' half, which is a waste of cells. What I'd do would be to initialise the histogram entries of the locked-down colours with large weights before starting the histogram count, and then after quantization for each of the locked colours snap the closest of the output palette entries to that colour.
Hmmm... Inserting new histogram entries with large weights for these "important" colours should only be done after checking that all of them are present in the image. It should be possible for the user to select the "web-safe" palette even if only 3 or 4 of these colours are present in the image. The generated palette would contain these 3 or 4 colours but none of the others. The goal is to make it easy for the user to specify a set of colours with special constraints, even if the image is only using a small subset of these colours. So I can see two solutions: - Insert an additional pass over the image, checking how many colours from that set should be inserted in the histogram before generating the optimal palette. - Generate the optimal palette first, then try to match these new colours with the ones specified as locked-down colours. This saves a pass over the image, but there is a risk of loosing some of the important colours if there are only a few pixels using them in the image.
> Hmmm... Inserting new histogram entries with large weights for these > "important" colours should only be done after checking that all of > them are present in the image. Perhaps. Presumably someone asked for them and they thought they knew what they were doing... If these colours don't end up ever being used they'll get pruned from the resulting palette anyway, but then we end up wasting cells. > It should be possible for the user to select the "web-safe" palette > even if only 3 or 4 of these colours are present in the image. The > generated palette would contain these 3 or 4 colours but none of the > others. That's already possible ('remove unused colors from final palette'), unless I am still failing to see exactly what this bug is talking about. > Generate the optimal palette first, then try to match these new > colours with the ones specified as locked-down colours. This saves > a pass over the image, but there is a risk of loosing some of the > important colours if there are only a few pixels using them in the > image. That's why I suggested putting the lock-down colours in the histogram with massive weights.
Maybe this little scenario will make the problem easier to understand: Let's assume that I have an image that contains several flat areas using "web-safe" colours (for example: black, white, orange and purple). The other parts of the image have several gradients and shadows using many different colours. Since I want to minimize the size of the final image, I tell the Gimp to generate an optimal palette containing only 32 colours and I convert from RGB to indexed without dithering. I also want any web-safe colours to remain unchanged, so I select the whole web palette as the set of locked-down colours (entering a different subset of this palette for each image would be quite tedious, so I simply select the whole palette). What I expect as a user is that the Gimp will see that only 4 web-safe colours (out of 216) are used in the image and allocate the remaining 28 slots for other colours.
Okay, I think I have a fair solution for this (but only in my head) that avoids the gotchas most of the time. At this point it'd likely be too late for the 2.0 freeze though.
Scratch that, it doesn't trivially address Raphaël's last requirement (automatically not-locking-down colours that are in the lock-down group if they're not used). Though that could be done with (yet) another pass.
Created attachment 30019 [details] Script that attempts to provide the functionality needed but fails :) This script is a test for a method that can work to accomplish this task. Unfortunately the PDB lacks functions for creating, editing and deleting palettes, so there are two steps that must be done manually. I have first checked that these two operations generate the same image: 1) Convert an image to indexed letting GIMP choose the optimal cmap. 2) Same as in (1) but then import the cmap as a palette, then convert the original image to indexed using that palette. So all we need now is the correct palette, and that's what the script generates because it can't go further. This palette has the colors that are common to the image and to the specified palette (as required by this bug report) and generates the rest up to a given number N. It neglects to check for overflow (i.e. if the number of used colors equals or exceeds N then no color should be added, but the script doesn't check that). It works with single-layer RGB images only, but admits images with alpha. The palette is generated as a Nx1 image. From there you have to rightclick the palette list and click Import. Then select the generated image as source. Now use the resulting palette to convert the original image to indexed. You can now close the image and delete the palette. It would probably have been easy to add the "Remove Unused Colors" check but I've decided to leave it out for simplicity. Currently it always removes unused colors. Unfortunately there's no SF-PALETTE widget so the palette with the colors to lock has to be entered as a string. Note that with very bad luck it may happen that the generated part of the palette matches one of the colors of the locked part. That's fortunately very uncommon. The script makes a final conversion to indexed for removing all possible duplicates.
N.B.: I realize that this script is an automatization of the second workaround mentioned in the description of bug #66257 (comment zero, so to say).
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gimp/issues/14.