I'm trying to reduce the download size of transparent PNGs by decomposing them into color and alpha images. This approach works fine, for my customer's images the size is reduced by over 50%.
To recompose the images I'm experimenting with both SVG and canvas.
The SVG solution uses an opacity mask, and the canvas uses the globalCompositeOperation.
The problem is, the SVG incorrectly shows dark edges when down-scaling (either by specifying the size in CSS or directly on the SVG). These dark edges do not appear when rendering the SVG at the same size of the input images. The canvas works fine. This happens in all browsers I tested (Chrome, IE11, Firefox)
The problem I believe, is that the SVG will independently resize the alpha-image and color-image, and then apply the opacity mask. However this approach does not work. In image processing it is well known that to resize a transparent image, one either has to pre-multiply the color components by the alpha, and then use a standard resizing algorithm, or one has to perform a weighted average (since mostly transparent pixels have less impact on the final color). See for example this discussion
When applying SVG filter effects, one could initially tweak the intermediate resolution that is used, but I can't figure out how to do this when using the SVG mask property (Robert Longson correctly pointed out to me that the filter effects do not support this anymore, since the filterRes
attribute was deprecated)
Here's the SVG code (our run it directly from my website in any HTML5 compliant browser)
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='1000' height='454' viewBox='0 0 2560 1162'>
<defs>
<mask id='mask'>
<image color-interpolation='sRGB' image-rendering='optimizeQuality' width='2560px' height='1162px' xlink:href='first-A.png'></image>
</mask>
</defs>
<image color-interpolation='sRGB' image-rendering='optimizeQuality' mask='url(#mask)' width='2560px' height='1162px' xlink:href='first-RGB.png'></image>
</svg>
Does anyone know how to tweak the SVG mask effect so that these edge artifacts do not appear?
Thanks a lot,
Peter