Alpha Compositing Algorithm (Blend Modes)

前端 未结 1 1174
遇见更好的自我
遇见更好的自我 2021-02-02 03:22

I\'m trying to implement blend modes from the PDF specification, for my own pleasure, in SASS.

PDF Specification: http://www.adobe.com/content/dam/Adobe/en/devnet/acroba

1条回答
  •  星月不相逢
    2021-02-02 03:54

    The SVG spec has a lot of good equations for various blending modes. And yes, you do have to calculate both the new alpha and the new colour -- for each channel. For standard blending modes, the alpha is calculated this way:

    alpha_final = alpha_bg + alpha_fg - alpha_bg * alpha_fg
    

    Note: I see you're considering alpha to be between 0 and 1, which is good. Alpha values in CSS are always defined as float values from 0 to 1; it's good to stick with this convention, because it makes the calculations immensely easier.

    It helps to 'premultiply' each colour channel by its alpha; these are more helpful for interpreting and using the usual formulae:

    colour_bg_a = colour_bg * alpha_bg
    

    In other words:

    red_bg_a = red_bg * alpha_bg
    green_bg_a = green_bg * alpha_bg
    blue_bg_a = blue_bg * alpha_bg
    

    Then, for plain-jane alpha compositing (like overlaying sheets of tracing paper, also known as src-over in Porter and Duff's original paper and the SVG alpha compositing spec), you take each channel and calculate it thus:

    colour_final_a = colour_fg_a + colour_bg_a * (1 - alpha_fg)
    

    The last step is to 'un-multiply' each final colour channel value by the final alpha:

    colour_final = colour_final_a / alpha_final
    

    and put it into your mixin somehow:

    rgba(red_final, green_final, blue_final, alpha_final)
    

    The other blending modes (multiply, difference, screen, etc) are slightly more complicated formulas, but the concept for every single mode is the same:

    1. Separate the R, G, B, and A values of both the foreground and background colours
    2. Calculate the alpha of the new, final colour with the above formula
    3. Pre-multiply all the R, G, and B values by their alpha value
    4. Calculate the new, final R, G, and B values (insert blending mode formula here)
    5. Un-multiply the final R, G, and B values by the final alpha
    6. Clip the final R, G, and B values so that they are between 0 and 255 (necessary for some modes, but not all)
    7. Put the colour back together again!

    If you're still interested in this, I've been doing the very thing in Stylus. You can see my progress here: https://github.com/pdaoust/stylus-helpers/blob/master/blend.styl You might be able to use it as a starting point for your own Sass mixin.

    The first thing I do is convert all the R, G, and B values from 0 - 255 values to 0 - 1 float values for the purposes of the calculations. Dunno if that's necessary, and it does require converting them back to 0 - 255 values. It felt right to me, and Porter and Duff worked in 0 - 1 float values in their original paper.

    (I'm encountering trouble with some of the compositing modes, which produce wildly different results from the expected results that the SVG spec pictures. I suspect that the spec gives the wrong equations. If anyone knows about Porter/Duff blending modes, I'd be very grateful for their help!)

    0 讨论(0)
提交回复
热议问题