我正在尝试使用 Magick++ / ImageMagick 7 读取索引/调色板/颜色映射 PNG image,但我找不到有关如何执行此操作的正确示例。从文档here我了解到这段代码应该读取像素/索引:
imtest.cpp:
#include <iostream>
#include <Magick++.h>
int main(int argc, const char *argv[])
{
std::cout << "Reading " << argv[1];
Magick::Image img;
try
{
img.read(argv[1]);
}
catch (const Magick::Exception &ex)
{
throw std::runtime_error("Failed to read image");
}
auto imgSize = img.size();
std::cout << " -> " << imgSize.width() << "x" << imgSize.height() << ", ";
if (img.classType() == Magick::ClassType::PseudoClass && img.type() == Magick::ImageType::PaletteType)
{
std::vector<uint8_t> data;
std::cout << "paletted, " << img.colorMapSize() << " colors" << std::endl;
// get palette indices as unsigned chars
const auto nrOfColors = img.colorMapSize();
// auto pixels = img.getConstPixels(0, 0, img.columns(), img.rows()); // needed to call this first for getConstMetacontent to work?
auto indices = static_cast<const uint8_t *>(img.getConstMetacontent());
const auto nrOfIndices = img.columns() * img.rows();
for (std::remove_const<decltype(nrOfIndices)>::type i = 0; i < nrOfIndices; i++)
{
data.push_back(indices[i]);
}
std::cout << "Read " << data.size() << " pixels" << std::endl;
}
else
{
throw std::runtime_error("Unsupported image format");
}
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBMAGICK REQUIRED IMPORTED_TARGET
Magick++
)
add_definitions(-DMAGICKCORE_HDRI_ENABLE=0)
add_definitions(-DMAGICKCORE_QUANTUM_DEPTH=16)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 11)
add_executable(imtest imtest.cpp)
target_include_directories(imtest PRIVATE ${ImageMagick_INCLUDE_DIRS})
target_link_libraries(imtest PkgConfig::LIBMAGICK)
与
imtest <image>
一起跑步
这是正确的,还是我做错了什么? getConstMetacontent() 中有一个 bug 最近已修复,但我仍然不知道我所做的是否正确。
在 ImageMagick 6 / Magick++ 中,获取索引像素数据的函数称为 getConstIndexes(),但它不再存在。
使用Magick++读取IndexChannel的正确代码是:
#include <iostream>
#include <Magick++.h>
int main(int argc, const char *argv[])
{
std::cout << "Reading " << argv[4];
Magick::Image img;
try
{
img.read(argv[4]);
}
catch (const Magick::Exception &ex)
{
throw std::runtime_error("Failed to read image");
}
auto imgSize = img.size();
std::cout << " -> " << imgSize.width() << "x" << imgSize.height() << ", ";
if (img.classType() == Magick::ClassType::PseudoClass && img.type() == Magick::ImageType::PaletteType)
{
std::vector<MagickCore::Quantum> data;
std::cout << "paletted, " << img.colorMapSize() << " colors" << std::endl;
img.channel(MagickCore::IndexChannel);
auto pixels = img.getConstPixels(0, 0, img.columns(), img.rows());
for (std::size_t i = 0; i < img.columns() * img.rows(); i++)
{
auto value = *pixels++;
std::cout << value << ", ";
data.push_back(value);
}
std::cout << "Read " << data.size() << " pixels" << std::endl;
}
else
{
throw std::runtime_error("Unsupported image format");
}
}