1

Given a set of colors, say colors on this webpage, and another palette of an equal number of colors, what would be a good way to map the former to the latter while:

  • preserving contrast between individual colors
  • preserving the relative intensity of the colors (not sure how important this would be)

Essentially, this webpage should be rendered in the new color palette while still legible.

What color space would be appropriate for this task?

Can you also point me to any related work?

Update: The mapping can surely be done manually but I intend to automate the mapping for any given set of colors and palette and so I'm looking for an algorithmic approach or rather an understanding of what properties need to be preserved in favor of legibility and beauty.

5
  • Well the webpage will be in an RGB colourspace, of course, and the model will be hexadecimal, as is the case with basically all HTML (this site is CSS based, of course) so mapping can be a manual task, can use colour model system tools of various kinds, could use Adobe's Illustrator's recolour tools, or any other systematic approach. I might well use galactic.ink/sphere Jan 15, 2019 at 21:58
  • @GerardFalla Thanks! I basically want to automate the mapping. So, I'm looking for a more algorithmic approach. I understand that the recolur tools allows me to repaint individual colours of an image while the other tool from galactic.ink allows me to choose intersting color palettes. But I do have a palette of colours already and need to decide what the best mapping would be from the colors of the image/website to this palette. Jan 16, 2019 at 3:25
  • Understood. But - the recolour tool, and the sphere tool, allow you to set a scheme, and then with the scheme set, alter the hue angle of the primary tone and it shifts the whole sequence, keeping relative hue angles, value shifts and contrast all constant between new versions of that basic scheme - is that not largely want you want, but non-algorithmic? Jan 16, 2019 at 4:43
  • 1
    @GerardFalla Ok, that makes sense. If I understood correctly, I can rotate the hue of all the colors on the web page so that the hues of the primary color in the web page and the new color scheme are aligned. This definitely takes care of relative contrast and intensities. However, the rest of the colors may not fall into the new color scheme. But this is definitely a good starting point. Thanks again! Jan 16, 2019 at 5:14
  • Based on our comment-scussion, I turned this into an answer for you to evaluate, accept or comment on, which is a more appropriate way of handling this - apologies for my shortcutting the GDSE system as I did with my initial comment! Jan 16, 2019 at 15:55

2 Answers 2

1

Here an attempt to answer your question. Or at least give you some inspiration. (I'm not an expert in color math so this might be a naive approach - but it seems to work.)


The method

We have a source palette with our original colors and a target palette with a new set of colors.

The goal is to find a way to map the target palette to the source palette where the relationship between the colors is preserved as well as possible. The RGB values aren't useful as they are, so we convert them to HSL. (Hue is normalized by dividing by 360.)

For each adjacent pair of colors in the source palette we now calculate the difference in hue, saturation and lightness. The last color is compared to the first. This sequence of differences is the pattern we are trying to match.

The colors of the target palette can be ordered in n! different ways so in this example with four colors we have 4 × 3 × 2 × 1 = 24 permutations (possibilities).

For each permutation we again calculate the sequence of HSL differences. Now we can compare the source palette to each of the permutations of the target palette and find the absolute deviation between each of the HSL differences. The deviations are added up to create a score for each permutation.

To find the best fit we simply choose the permutation with the lowest score.

This is also the sequence I would have chosen intuitively, so the idea seems to work.

Limitations and problems

  • The source and target palettes must have the same number of colors.
  • The method fails if any of the colors are neutral (saturation = 0) because then hue isn't a number (not 0 as Photoshop wrongly indicates) and we can't do a proper comparison. I don't know how to fix this. We could just disregard hue in those cases, but I'm unsure if it breaks the logic. So until further notice no grays, black or white.
  • If the distribution of the source colors is very different from the distribution of the target colors, the result won't be very pleasing.
  • The method gives hue, saturation and lightness the same significance. This might not be what you want in all cases.

Implementation

I have made a quick implementation in javascript. Try it in this JSFiddle.

4
  • Great Work! It is is the closest to what I was looking for, so I'll accept this answer. Another limitation that I would like to add is that it does not scale with palette size (example: 8! = 40,320 combinations). I'm working on an alternate approach based on optimization. If it works out, I'll definitely share the results here Jan 25, 2019 at 9:47
  • Glad you liked it, @rhino2rhonda. It was a fun challenge. It surely could be optimized in many ways (and I might try to do it for fun). 8 colors "only" takes about 80 ms to calculate but 10 colors takes about 6000 ms so it is quite slow. I'm looking forward to see your take on it. But don't forget that I'm just assuming that this method works because it seems logical and because I keep getting pleasing results. I don't have enough knowledge to prove that it's correct.
    – Wolff
    Jan 25, 2019 at 22:10
  • Slightly off topic @Wolff, but do you mind sharing how you created these images? Did you generate any of it with code and what did you use for labeling the palettes? Jan 26, 2019 at 9:20
  • 1
    @rhino2rhonda, I made it manually in InDesign. But you could make something similar with html.
    – Wolff
    Jan 26, 2019 at 9:28
1

Well the webpage will be in an RGB colourspace, of course, and the model will be hexadecimal, as is the case with basically all HTML (this site is CSS based, of course) so mapping can be a manual task, can use colour model system tools of various kinds, could use Adobe's Illustrator's recolour tools, or any other systematic approach. I might well use galactic.ink/sphere to do this.

Bear in mind that the recolour tool, and the sphere tool, allow you to set a custom scheme, and then with your scheme set, alter the hue angle of the primary tone and it shifts the whole sequence, keeping relative hue angles, value shifts and contrast all constant between new versions of that basic scheme; though clearly this is not algorithmic, I think it gets you the function you need for now, and might be a starting point for a coding effort to create an algorithmic system.

Sphere colour position 01 Sphere 01

Sphere - same scheme rotated to position 02 enter image description here

Same relationships - different colour scheme.

The same approach but more flexibly implemented in Adobe Illustrator's recolour tools (allows your custom schemes easily):

Illustrator file with one colour swatch group, each swatch applied to one rectangle: enter image description here

Rectangles alt-drag copied, with them still selected, Colour Guide invoked: enter image description here

Click in New Group at right upper bezel: enter image description here

You can name your new group if you wish - then click on the Edit button at mid-pane left: enter image description here

This brings up the colour sphere editor, which has your scheme loaded into the nodes, and the unbroken chain at bottom right of the colour sphere editor pane indicates the relationships will be enforced if you change hue angle or value: enter image description here

Rotate the hue angle of one of the nodes or the primary node and they all move. Shift in/out to change value, and again, they all maintain relative positions... once you have something which you feel meets your needs for a new scheme, on the right-hand pane click the "Save to disk" symbol and the changes you've made will be saved in your new group. enter image description here

As you can see, this has also recoloured your selected items to your new scheme as well. enter image description here

When you exit the Colour Guide, the new group you created is visible in your basic swatches palette also. enter image description here

5
  • 2
    Your answer is good, but it seems to me that the OP ask for something slightly different. He/she wants to map the colors from one existing palette to another existing palette. Not just modify an existing palette to a different palette. That is not a simple task - maybe even impossible.
    – Wolff
    Jan 16, 2019 at 16:30
  • @Wolff - understood. My hope was that this provide a starting point - whether directly for a coding effort or as an exemplar to a code poet - not only is this not the same as mapping two existing unique palettes, it's also not automated. Jan 16, 2019 at 17:01
  • @GerardFalla This is great! Thanks for your efforts. Jan 17, 2019 at 5:54
  • 1
    @Wolff It's not a trivial task, but surely not impossible. One way, for example, assuming a small palette of colors, is to evaluate all mappings and pick the one that best satisfies the constraints related to contrast, hue, etc. This seems like a problem that someone might have tackled before and I am hoping to be lead to a more sophisticated solution. Even an approximate mapping to the new palette should be fine. Jan 17, 2019 at 6:00
  • 1
    You might be right @rhino2rhonda. I'm actually working on a javascript based solution right now which seems promising. Gonna take some time to turn it into an answer though.
    – Wolff
    Jan 18, 2019 at 16:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.