检测PNG图片文件是否为透明图片?

20

我正在寻找一种快速确定PNG图像是否具有透明特征的方法。也就是说,图像的任何部分是否半透明或以任何方式显示背景。有人知道检测这一点的简单方法吗?

更新:好的,除了提取PNG规范并编写代码,是否还有更简单的方法?


1
你到底在寻找什么?是 alpha 通道的存在吗?还是在 8 位 PNG 调色板中声明透明颜色?还是完全透明像素的存在?半透明像素和调色板条目呢? - Michael Madsen
我正在寻找确定PNG图像的任何方面是否使图像的任何部分半透明并以任何方式显示背景的方法。 - kenny
3个回答

19
为什么不只是循环遍历图像中的所有像素并检查它们的透明度值?
    bool ContainsTransparent(Bitmap image)
    {
        for (int y = 0; y < image.Height; ++y)
        {
            for (int x = 0; x < image.Width; ++x)
            {
                if (image.GetPixel(x, y).A != 255)
                {
                    return true;
                }
            }
        }
        return false;
    }

11
记住,使用GetPixel方法非常慢。你应该使用Bitmap.LockBits方法获取指向图像数据的指针,并使用不安全代码处理图像。每次调用GetPixel方法都会锁定图像位,获取像素数据,构建一个Color结构,然后解锁图像位,需要更多的处理时间,因此使用这种方法需要更多的处理时间。 - jrista
我希望有比检查每个像素更快的方法。但这肯定比RTM容易。我需要决定是否有时间进行暴力检查。谢谢。 - kenny
2
如果第一个像素是透明的,从循环内部返回true会更有效率,因此可以立即退出。 - Tim Booker

4

嗯,我还不完全理解这个问题,但是如果您只想检查给定的图像是否可以使用透明功能,您可以使用以下代码:

Image img = Image.FromFile ( "...", true );
if ( (img.Flags & 0x2) != 0)
{
}

虽然它不能帮助您确定给定的png文件是否实际上使用透明功能,但是它会根据png文件规范指示它具有颜色类型4或6(两者都支持透明度)。


谢谢,但这对我没有帮助,因为我需要知道图像是否实际上是半透明的,而不是可能是。上面的另一个答案可以解决问题,但我希望有更快的方法,而这显然不是... - kenny
1
这非常有用。我已经将它与上面的代码结合使用,所以只检查支持透明度的图像的像素。 - Tim Booker
@apathetic PNG的颜色类型3通过tRNS块也支持透明度。 - Kornel
1
这对于索引图像无效。它们似乎总是返回Flag 2,即使它们不透明。 - Nyerguds

1
这里有一个有效的方法: 以二进制方式打开PNG文件。 搜索第26个字节(从零开始算则是第25个)。 评估字符的字节值: 2或更低 => 绝对不透明, 3或更高 => 支持透明度。 根据我的研究,Photoshop生成的文件仅在需要时使用3或更高版本,因此这是一种可靠的方法来判断是否使用这些文件。看起来几乎所有文件的不透明度为2,混合阈值为6。 您还可以考虑检查在该区域附近找到的PNG和IHDR字符串,以确保您的代码无误。

似乎没有办法对调色板图像进行此操作;即使GIMP将图像视为完全不透明,它们仍然有“3”。 - Nyerguds
这种方法仅适用于不透明的答案。否则,您需要检查整个图像。至于不必要的误报,您会惊讶地发现有多少GIF设置了透明位而没有理由。我最近在我的网站画廊中编写了GIF透明度识别代码,以使效果更好。然后,由于愚蠢的软件制作这些图片,它产生了很多误报。我只是在十六进制编辑器中编辑了文件(不想重新压缩),就解决了这个问题。 - Zdenek
顺便提一下,重新考虑使用调色板PNG。它们在索引模式下的压缩性能较差。 - Zdenek
呵呵,如果那么简单就好了。我正在开发的程序可以从小说写作网站上的文章创建电子书(epub格式),并确保正确保存和嵌入其中的任何图像。由于一些电子阅读器无法处理透明度,因此我允许将这些图像压缩在白色背景上,但由于.Net中的png编写非常不优化且经常增加文件大小,因此我想检查是否实际需要重新保存。但我几乎不能对人们发布到他们的故事中的图像负责。 - Nyerguds
我向您推荐 pngcrush 工具。它(几乎总是)能找到给定图像的最佳压缩参数。没有质量损失,但会丢弃 ICC,因此仅适用于 sRGB 文件。当文件来自可怕的 Microsoft 产品时,它通常可以节省超过30%的大小。很少情况下,Photoshop 生成的文件比 pngcrush 能做到的小约0.1%,因此有改进的方法。 - Zdenek
嗯,这又是一个要添加到程序中的第三方库。不过目前,我会选择检测;我已经找到了一种相当好的方法。 - Nyerguds

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接