ImageMagick C++ API get channels of image

时间:2015-09-01 22:50:41

标签: c++ api imagemagick

I want to retrieve information about how channels in an image are used. Used library ImageMagick version 6.9.1, Qt5, C++.

QString ImageMagick::test(){
    qDebug()<<"magickimage test";
    Magick::Image magickimage;
    try {
        magickimage.read(qUtf8Printable("poster383x357.jpg"));
    }
    catch (Magick::Warning &error_ ) {
        qDebug()<<QString("Warning %1").arg(error_.what());
        return "";
    }
    catch (Magick::Error &error_ ) {
        qDebug()<<QString("Error %1").arg(error_.what());
        return "";
    }
    if (magickimage.isValid()){
        qDebug()<<"magickimage w x h:"<<magickimage.columns()<<magickimage.rows();
        qDebug()<<"magickimage depth"<<magickimage.depth();
        int channels = (int)MagickCore::GetImageChannels(magickimage.image());
        qDebug()<<"magickimage channels:"<<channels;
    }
    return "";
}

But the return is:

magickimage test
magickimage w x h: 383 357
magickimage depth 8
channels: 0

I know that image (poster383x357.jpg) have 24 bits per pixel 24/8=3 channels. Answer must be channels: 3.

1 个答案:

答案 0 :(得分:0)

更新了答案......

请记住,通道计数对于颜色空间是主观的。 MagickCore::ImageInfo结构将包含channel属性;其中,是ChannelType的调查员。使用按位比较和尊重颜色空间,图像中的总通道可以计算为......

Magick::Image img("rose:");
MagickCore::ImageInfo * info = img.imageInfo();
int channel_count = 0;

// Have Red, or Cyan (CMYK), or Gray
if ((info->channel & Magick::RedChannel) != 0) channel_count++;

// Have Green, or Magenta (CMYK)
if ((info->channel & Magick::GreenChannel) != 0) channel_count++;

// Have Blue, or Yellow (CMYK)
if ((info->channel & Magick::BlueChannel) != 0) channel_count++;

// Check for Alpha channel (if enabled)
if (((info->channel & Magick::OpacityChannel) != 0)
   && (img.matte() != Magick::MagickFalse)) channel_count++;

// Have Black channel in CMYK image
if (((info->channel & Magick::IndexChannel) != 0)
   && (img.colorSpace() == Magick::CMYKColorspace)) channel_count++;

std::cout << "Total channels : " << channel_count << std::endl;
//=> Total channels : 3

原始答案......

如果您正在尝试评估频道的布局方式,那么您应该使用Magick::Image.colorSpace评估图像的色彩空间,如果您使用的是格式类型,则应评估Magick::Image.magick。在IM-6中,这通常是4(RGBA)或5(CMYKA)个通道,颜色空间假定数据如何占用通道。

您可以使用Magick::quantizeInfo来评估数据在内存中的结构(?)。

std::ostream& operator<<(std::ostream& os, const MagickCore::QuantizeInfo& info)
{
  os << "number of colors : " << info.number_colors << std::endl;
  os << "tree depth       : " << info.tree_depth << std::endl;
  os << "dither           : " << info.dither << std::endl;
  return os;
}

int main(int argc, const char * argv[]) {
  Magick::InitializeMagick(argv[0]);
  Magick::Image img("rose:");
  MagickCore::QuantizeInfo * qInfo = img.quantizeInfo();
  std::cout << "Quantize Info\n" << *qInfo << std::endl;
  return 0;
}

哪会输出类似......

Quantize Info
number of colors : 256
tree depth       : 0
dither           : 1

如果您尝试确定统计信息...... Magick::Image.statistics更理想。实施例...

std::ostream& operator<<(std::ostream& os, const Magick::Image::ImageChannelStatistics& channel)
{
  os << "maximum  : " << channel.maximum << std::endl;
  os << "minimum  : " << channel.minimum << std::endl;
  os << "mean     : " << channel.mean << std::endl;
  os << "std dev  : " << channel.standard_deviation << std::endl;
  os << "skewness : " << channel.skewness << std::endl;
  os << "kurtosis : " << channel.kurtosis << std::endl;
  return os;
}

int main(int argc, const char * argv[]) {
  Magick::InitializeMagick(argv[0]);
  Magick::Image img("rose:");
  Magick::Image::ImageStatistics stats;
  img.statistics(&stats);
  std::cout << "Red\n---\n" << stats.red << std::endl;
  // ...
  return 0;
}

哪会给......

Red
---
maximum  : 65535
minimum  : 8995
mean     : 37448
std dev  : 17808.9
skewness : 0.14637
kurtosis : -1.385

在ImageMagick 7中

ImageMagick的下一个主要版本支持1-32 +的任意数量的像素通道。请参阅Porting -> Pixel Channel指南。这个版本将引入一个方法GetPixelChannels,这可能是你期望的行为。

 // Un-tested and subject to change
 int channels = MagickCore::GetPixelChannels(magickimage.image());

但我离题了

  

有什么问题?

GetImageChannels返回0,因为您尚未设置任何频道。

size_t channels = MagickCore::GetImageChannels(img.image());
std::cout << channels << std::endl; //=> 0
MagickCore::SetImageChannels(img.image(), 1);
channels = MagickCore::GetImageChannels(img.image());
std::cout << channels << std::endl; //=> 1