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");
我试图找出图像 (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");