Magick++ 判断图像是否具有透明度

Magick++ find out whether an image has transparency

我试图找出图像 (Magick++-class) 是否是 opaque/has 透明像素。我当前的测试代码如下所示:

    Image orig;
    orig.read(inputPath.c_str());

    bool hasAlpha = orig.alpha();
    printf("Alpha: %s %s\n", inputPath.c_str(), hasAlpha ? "yes" : "no");

对于 jpg 正确输出“否”,对于具有透明度的 png 正确输出“是”,但不幸的是,对于没有透明像素的 PNG 也报告“是”。

使用命令 identify -format '%[opaque]' image.png,imagemagick 能够为所有文件正确检测到这一点,因此它能够找到这一点,但由于各种原因我想避免调用外部程序,我在文档中或通过 Google 找不到合适的方法。我如何通过 Magick++ 在代码中找到它?

谢谢!

似乎找出这个问题的唯一方法是手动检查所有像素。我的代码在下面,以防其他人将来遇到这个问题。使用这个之前要注意两件重要的事情:

  • 检查 alpha 通道的方法在 ImageMagick7 中似乎已重命名为 alpha,之前是 matte()。如果无法编译,请检查您的版本。
  • 我只检查缺失的 alpha 通道或 alpha 通道中的透明度。还有其他我不检查的透明方法(即​​将特定颜色设置为透明)。
// assumed preamble:
//#include <Magick++.h>
//using namespace Magick;

/**
 * Finds out whether an image is opaque (has no transparent pixels). Tested for jpeg and png inputs.
 * @param baseImage The image to check.
 * @return True if opaque, false otherwise.
 */
bool IsImageOpaque(const Image& baseImage) {
    // if the image has no alpha channel, we're done now
    if (!baseImage.alpha())
        return true;

    // if it does not work that simple, we need to check the alpha channel for non-opaque values
    // it seems to be best practice to clone the image beforehand
    Image img(baseImage);

    // find image width and height for iteration
    int imgWidth = img.columns();
    int imgHeight = img.rows();

    // iterate the whole image
    for ( int row = 0; row <= imgHeight; row++ )
    {
        for ( int column = 0; column <= imgWidth; column++ )
        {
            // get each pixel
            Color px = img.pixelColor( column, row );
            // opaque means that the alpha channel has the max value, so if we find a pixel where this condition is not
            // met, the image is not opaque
            if (px.quantumAlpha() != QuantumRange)
                return false;
        }
    }

    // if we did not exit early, we did not find a transparent pixel and, therefore, the image is opaque
    // note that we did *not* check for other transparency methods, such as a color which is marked as transparent (gif
    // uses this AFAIK), so be vary for inputs other than png or jpg.
    return true;
}

使用ImageMagick-7,我相信你需要的方法是Magick::Image::isOpaque();它调用相同的 MagickCore 方法来计算 '%[opaque]'.


bool hasAlpha = !orig.isOpaque();
printf("Alpha: %s %s\n", inputPath.c_str(), hasAlpha ? "yes" : "no");