美文网首页程序员
PNG格式为何不支持Premultiplied Alpha?

PNG格式为何不支持Premultiplied Alpha?

作者: 牛顿不相信二段跳 | 来源:发表于2019-11-23 18:59 被阅读0次

    本文首先叙述一段经历,然后得出结论,想看结论的可以直接跳到最后

    经历

    用一张带Alpha通道的PNG图片作为原始输入,然后用常用的PNG图片压缩工具pngquant处理得到压缩后的图片

    Original (144 KB).png Compressed (39 KB).png

    (图片来源: super-mario-odyssey-switch)

    压缩后图片从144 KB减小到39KB,而且几乎观察不到区别,但这不是本文重点

    接下来使用结构相似性算法(Structural Similarity Index,SSIM)求出两张图片的相似程度,主要的Python代码如下(Python 3.8)

    from skimage import io, metrics
    
    original_image = io.imread('Original(144 KB).png')
    compressed_image = io.imread('Compressed (39 KB).png')
    
    value = metrics.structural_similarity(original_image, compressed_image, multichannel=True)
    print('ssim value: %f'%value)
    

    然而求出的相似程度居然只有69%,让我对结果产生怀疑。仔细研究一番后发现某些像素点的RGB值在压缩之后产生了非常巨大的变化。Alpha等于零的像素,无论它的RGB值是多少,该像素最终都不可见。据此推断,压缩算法利用这个特点,在Alpha等于零的情况下大幅调整RGB以进一步对图像进行压缩

    因此,进行图片相似度评价之前,应该将RGB值预先乘以Alpha值,调整后的代码如下

    from skimage import io, metrics
    
    def premultiply_alpha(image):
        height = image.shape[0]
        width = image.shape[1]
        for y in range(height):
            for x in range(width):
                pixel = image[y, x]
                alpha = pixel[3]
                factor = alpha / 255
                image[y, x, 0] *= factor    # Red
                image[y, x, 1] *= factor    # Green
                image[y, x, 2] *= factor    # Blue
    
    original_image = io.imread('Original(144 KB).png')
    compressed_image = io.imread('Compressed (39 KB).png')
    
    premultiply_alpha(original_image)
    premultiply_alpha(compressed_image)
    
    value = metrics.structural_similarity(original_image, compressed_image, multichannel=True)
    print('ssim value: %f' % value)
    

    最终得到图片压缩前后的相似性是98%

    结论

    回答标题的问题,PNG格式不支持Premultiplied Alpha原因(不一定准确)

    • 对PNG格式而言,(0, 0, 0, 0) 与 (100, 100, 100, 0)没有区别,因为它们最终都不可见
    • 对Premultiplied Alpha而言,RGB值需要预先乘以Alpha,因此(100, 100, 100, 0)是不存在的像素,因为RGB在乘以0之后不可能还是100

    相关文章

      网友评论

        本文标题:PNG格式为何不支持Premultiplied Alpha?

        本文链接:https://www.haomeiwen.com/subject/ibfvvctx.html