代码之家  ›  专栏  ›  技术社区  ›  Alexander Shutau

如何应用feblend并保留源alpha

  •  2
  • Alexander Shutau  · 技术社区  · 7 年前

    我试图通过在“变亮”和“变暗”模式下对图像应用feflood和feblend来修改图像的颜色。如何保存alpha通道?

    <svg>
      <filter id="filter">
        <feFlood result="flood" flood-color="blue" />
        <feBlend in="SourceGraphic" in2="flood" mode="lighten" />
      </filter>
      <image filter="url(#filter)" href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" />
    </svg>
    

    https://jsfiddle.net/utqghr0o/

    2 回复  |  直到 7 年前
        1
  •  4
  •   Michael Mullany    7 年前

    亮光的工作方式是,它从两个输入(预先乘以alpha)的每个通道中获取最大颜色值。因此,如果一个像素的不透明度为零,它将永远不会算作任何通道的最大颜色,并且将使用来自其他输入的值。

    您需要做的是首先用源图像中的alpha(“sourcelpha”)屏蔽洪水,然后将屏蔽洪水与原始图像混合。

    <svg width="544" height="184">
      <filter id="filter">
        <feFlood result="flood" flood-color="blue" />
        <feComposite in="flood" in2="SourceAlpha" operator="atop" result="maskedflood"/>
        <feBlend in="SourceGraphic" in2="maskedflood" mode="lighten" />
      </filter>
      <image filter="url(#filter)" width="544" height="184" href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" />
    </svg>
        2
  •  2
  •   Michael Mullany    7 年前

    我认为保罗的回答很接近,但不完全正确。

    FeBlend配方为:

    Opacity of Final Pixel  = 1 - (1- Opacity of Image A Pixel)*(1- Opacity of Image B Pixel)
    

    如果你先做遮罩,然后混合,最终的不透明度将有点降低。例如,对于图像A中不透明度为0.6的像素,最终的像素不透明度为1-(.6*.6)=0.64。

    接近,但不等于0.6。

    如果要在最终图像中保留图像A的精确不透明度,需要先进行混合,然后进行遮罩。这是假设您希望在预乘的“100%不透明等效”颜色上进行照明,通常情况下是这样的。

    <svg width="544" height="184">
      <filter id="filter">
        <feFlood result="flood" flood-color="blue" />
    
        <feBlend in="SourceGraphic" in2="flood" mode="lighten" result="blend"/>
        <feComposite in="blend" in2="SourceAlpha" operator="atop" result="maskedflood"/>
      </filter>
      <image filter="url(#filter)" width="544" height="184" href="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" />
    </svg>