views:

58

answers:

2

I have an (R, G, B) triplet, where each color is between 0.0 and 1.0 . Given a factor F (0.0 means the original color and 1.0 means white), I want to calculate a new triplet that is the “watermarked” version of the color.

I use the following expression (pseudo-code):

for each c in R, G, B:
    new_c ← c + F × (1 - c)

This produces something that looks okayish, but I understand this introduces deviations to the hue of the color (checking the HSV equivalent before and after the transformation), and I don't know if this is to be expected.

Is there a “standard” (with or without quotes) algorithm to calculate the “watermarked” version of the color? If yes, which is it? If not, what other algorithms to the same effect can you tell me?

A: 

Why not just?

new_c = F*c

I think you should go first over watermarking pixels and figure out if it should be darker or lighter.

For lighter the formula might be new_c=1-F*(c-1)

ralu
That doesn't give white for F=1.0
andrewmu
It does for F = 0.0, first formula is for getting darker and second for getting lighter
ralu
F == 0.0 produces white in the second formula (which is the reverse of my formula except for that `c-1` which should be `1-c`), but I'm sure there is no single F that produces white in the first formula for all possible triplets. And anyway, I was specific: 0.0 original color, 1.0 white. Thanks anyway.
ΤΖΩΤΖΙΟΥ
+3  A: 

Actually this looks like it should give the correct hue, minus small variations for arithmetic rounding errors.

This is certainly a reasonable, simple was to achieve a watermark effect. I don't know of any other "standard" ones, there are a few ways you could do it.

Alternatives are:
Blend with white but do it non-linearly on F, e.g. new_c = c + sqrt(F)*(1-c), or you could use other non-linear functions - it might help the watermark look more or less "flat".

You could do it more efficiently by doing the following (where F takes the range 0..INF):

new_c = 1 - (1-c)/pow(2, F)

for real pixel values (0..255) this would convert into:

new_c = 255 - (255-c)>>F

Not only is that reasonably fast in integer arithmetic, but you may be able to do it in a 32b integer in parallel.

andrewmu
Do you know: is my algorithm the same as blending white with opacity F over the initial colour? Because that would be an alternative, but I think it's the same. Anyway, if you do know other ways to do it, please update your answer. Thank you.
ΤΖΩΤΖΙΟΥ
Yes, your way is the same as blending white with opacity F, exactly right.
andrewmu