How to use pre-multiplied during image convolution to solve alpha bleed problem?

最后都变了- 提交于 2019-12-02 20:52:52
Mark Ransom

tkerwin has already provided the correct answer, but it seems to need further explanation.

The math you've shown in your question is absolutely correct, right up until the end. It is there that you're missing a step - the results are still in a pre-multiplied alpha mode, and must be "unmultiplied" back to the PixelFormat32bppARGB format. The opposite of a multiply is a divide, thus:

finalRed = finalRed * 255 / finalAlpha;
finalGreen = finalGreen * 255 / finalAlpha;
finalBlue = finalBlue * 255 / finalAlpha;

You've expressed a concern that the divide might create a result that is wildly out of range, but that won't happen. If you trace the math, you'll notice that the red, green, and blue values can't be greater than the alpha value, because of the pre-multiplication step. If you were using a more complicated filter than a simple box blur it might be a possibility, but that would be the case even if you weren't using alpha! The correct response is to clamp the result, turning negative numbers into 0 and anything greater than 255 into 255.

Following the advice in your link, you pre-multiply before blurring and un-pre-multiply after blurring. In your example, pre-multiplying actually does nothing, since there are no semi-transparent pixels. You did the blur, then you need you un-pre-multiply by doing (assuming normalized color values from 0 to 1):

RGB' = RGB/A  (if A is > 0)
A' = A

This will get you a non-pre-multiplied blurred final image.

Both answers appear wrong here.

Use the proper blending mode, which according to Porter Duff is:

FG.RGB + (1.0 - FG.Alpha)*BG.RGB

Not sure where the rest of the answers are coming from, but wow.

The alpha encoding dictates the over operation.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!