‘Unblend’ Background Colour

Kristjan Kannike, created 2024-05-01, changed 2024-05-02

Instead of choosing two semi-transparent colours to blend, choose a background colour and the blended colour and find the  source (foreground) colour.

Different opacities for background and source (foreground) colours:

unblendForeground[cb_?ColorQ,cr_?ColorQ,ab_?NumericQ,as_?NumericQ]:=Block[{colspace=Head[cb],cs=RGBColor@@MapThread[((ab (-1+as))/as) #1+(1-((ab (-1+as))/as)) #2&,{List@@ColorConvert[cb,RGBColor],List@@ColorConvert[cr,RGBColor]}]},
If[(Min@@cs)<0||(Max@@cs)>1,Print["Warning: the colours cannot be unblended (negative or too large components needed)."]];
ColorConvert[cs,colspace]
]

The same opacity for background and source (foreground) colours:

unblendForeground[cb_?ColorQ,cr_?ColorQ,a_?NumericQ]:=unblendForeground[cb,cr,a,a];

Unblend the background colour from the source (foreground) colour and the mixture:

unblendBackground[cr_?ColorQ,cs_?ColorQ,ab_?NumericQ,as_?NumericQ]:=Block[{colspace=Head[cs],cb=RGBColor@@MapThread[(as/(ab (-1+as))) #1-(((ab+as-ab as))/(ab (-1+as))) #2&,{List@@ColorConvert[cs,RGBColor],List@@ColorConvert[cr,RGBColor]}]},
If[(Min@@cb)<0||(Max@@cb)>1,Print["Warning: the colours cannot be unblended (negative or too large components needed)."]];
ColorConvert[cb,colspace]
]

The same opacity for source and background colours:

unblendBackground[cr_?ColorQ,cs_?ColorQ,a_?NumericQ]:=unblendBackground[cr,cs,a,a];

Because unblending the source (foreground) colours seems more common, give it a shorter synonym:

unblend=unblendForeground;

lightred=;
lightblue=;

The unblended colour tends to be brighter than the original:

unblend[lightred,lightblue,0.5]

Especially in the case of finding the background:

unblendBackground[lightblue,lightred,0.5]

Light blue on light red produces a reddish grey blend:

With[{op=0.5},Graphics[{Opacity[op],lightred,Rectangle[{0,0}],Opacity[op],lightblue,Rectangle[{1/3,1/3}]}]]

Set the blended colour to light blue:

With[{op=0.5},Graphics[{Opacity[op],lightred,Rectangle[{0,0}],Opacity[op],unblend[lightred,lightblue,op],Rectangle[{1/3,1/3}]}]]

Use different opacities for the colours:

With[{opRed=0.3,opBlue=0.5},Graphics[{Opacity[opRed],lightred,Rectangle[{0,0}],Opacity[opBlue],unblend[lightred,lightblue,opRed,opBlue],Rectangle[{1/3,1/3}]}]]

Unblend the background colour instead:

With[{op=0.5},Graphics[{Opacity[op],unblendBackground[lightblue,lightred,op],Rectangle[{0,0}],Opacity[op],lightred,Rectangle[{1/3,1/3}]}]]

Not every colour can be unblended with every background or opacity:

unblend[lightblue,lightred,0.5]