繁体   English   中英

Magick++ ``depth`` 的行为与 ``convert -depth`` 不同

[英]Magick++ ``depth`` does not behave the same as ``convert -depth``

我通过我之前的问题发现,当我在 ImageMagick 的convertMagick++中使用depth时,它的工作方式似乎有所不同。

CLI 版本和结果

使用:

$ convert /foo/bar.ppm -depth 1 /foo/out.ppm

我得到一张 output 图像,经过检查,它显示了 1 位颜色深度:

$ identify /foo/out.ppm

out.ppm PPM (blah blah) 1-bit sRGB (blah blah)

C++ 版本和结果

使用代码:

#include <Magick++.h>

int main(int argc, char **argv) {
    Magick::InitializeMagick(*argv);
    Magick::Image img;
    img.read("/foo/bar.ppm");
    Magick::Image temp_img(img);
    temp_img.depth(1);
    temp_img.write("/foo/out.ppm");
    return 0;
}

使用命令编译:

g++ -std=c++17 test.cpp -o test `Magick++-config --cppflags --cxxflags --ldflags --libs`

产生 output:

$ identify /foo/out.ppm

out.ppm PPM (blah blah) 8-bit sRGB (blah blah)

硬件

我在以下位置运行了相同的结果:

  • Raspberry Pi - Raspbian 10(克星)
  • 笔记本电脑 - Ubuntu 18.04(仿生海狸)

软件(在树莓派上)

$ apt list --installed | grep magick

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

graphicsmagick-libmagick-dev-compat/stable,now 1.4+really1.3.35-1~deb10u1 all [installed]
imagemagick-6-common/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,automatic]
imagemagick-6.q16/now 8:6.9.10.23+dfsg-2.1 armhf [installed,upgradable to: 8:6.9.10.23+dfsg-2.1+deb10u1]
imagemagick/now 8:6.9.10.23+dfsg-2.1 armhf [installed,upgradable to: 8:6.9.10.23+dfsg-2.1+deb10u1]
libgraphics-magick-perl/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick++-q16-12/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick++1-dev/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick-q16-3/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libgraphicsmagick1-dev/stable,now 1.4+really1.3.35-1~deb10u1 armhf [installed,automatic]
libmagick++-6-headers/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,auto-removable]
libmagick++-6.q16-8/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,auto-removable]
libmagickcore-6-arch-config/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,auto-removable]
libmagickcore-6-headers/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,auto-removable]
libmagickcore-6.q16-6-extra/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,automatic]
libmagickcore-6.q16-6/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,automatic]
libmagickwand-6-headers/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,auto-removable]
libmagickwand-6.q16-6/stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 armhf [installed,automatic]

图片

我测试了多个sRGB类型的输入文件。 在开始测试之前,我将所有内容都转换为 NetBPM 格式,例如:

convert yourimage.jpg /foo/bar.ppm

问题

为什么 C++ 与 Bash 版本不同? 他们应该在后台链接到完全相同的代码。 深度的输入值不需要是特殊类型( Magick::Image.depth采用size_t )。 我的安装中有什么东西搞砸了吗? 我知道它大部分是基于 ImageMagick v6 因为 debian 回购是出了名的慢,但在源代码中没有任何改变(据我所知)应该影响depth

还有什么不行?

量化

添加:

temp_img.quantizeColorSpace(Magick::GRAYColorspace);
temp_img.quantizeColors(1);
temp_img.quantize( );

代码也应该是一种减少颜色深度的方法。 同样,这会在 C++ 中产生一个 8 位图像。

单色

这会在 CLI 和 C++ 中产生一个 8 位图像

我能想到的最接近的解决方案是使用“PBM”格式。

使用以下内容生成测试图像。

convert -size 10x10 plasma: input.jpg && convert input.jpg input.ppm

只需使用Magick::Image.magick方法。

#include <Magick++.h>

int main(int argc, char **argv) {
    Magick::InitializeMagick(*argv);
    Magick::Image img;
    img.read("input.ppm");
    Magick::Image temp_img(img);
    temp_img.magick("PBM");
    temp_img.depth(1);
    temp_img.write("output.ppm");
    return 0;
}

我们得到以下文件结构...

$ hexdump -C output.ppm 
00000000  50 34 0a 31 30 20 31 30  0a 00 00 00 00 00 00 06  |P4.10 10........|
00000010  00 ff 80 ff c0 ff c0 ff  c0 ff c0 ff c0           |.............|
0000001d

如果我们想要二进制数据的 ASCII 表示,只需禁用压缩。

    Magick::Image temp_img(img);
    temp_img.compressType(Magick::NoCompression);
    temp_img.magick("PBM");
    temp_img.depth(1);
    temp_img.write("output.ppm");

这将产生以下...

$ hexdump -C output2.ppm 
00000000  50 31 0a 31 30 20 31 30  0a 30 20 30 20 30 20 30  |P1.10 10.0 0 0 0|
00000010  20 30 20 30 20 30 20 30  20 30 20 30 20 0a 30 20  | 0 0 0 0 0 0 .0 |
00000020  30 20 30 20 30 20 30 20  30 20 30 20 30 20 30 20  |0 0 0 0 0 0 0 0 |
00000030  30 20 0a 30 20 30 20 30  20 30 20 30 20 30 20 30  |0 .0 0 0 0 0 0 0|
00000040  20 30 20 30 20 30 20 0a  30 20 30 20 30 20 30 20  | 0 0 0 .0 0 0 0 |
00000050  30 20 31 20 31 20 30 20  30 20 30 20 0a 31 20 31  |0 1 1 0 0 0 .1 1|
00000060  20 31 20 31 20 31 20 31  20 31 20 31 20 31 20 30  | 1 1 1 1 1 1 1 0|
00000070  20 0a 31 20 31 20 31 20  31 20 31 20 31 20 31 20  | .1 1 1 1 1 1 1 |
00000080  31 20 31 20 31 20 0a 31  20 31 20 31 20 31 20 31  |1 1 1 .1 1 1 1 1|
00000090  20 31 20 31 20 31 20 31  20 31 20 0a 31 20 31 20  | 1 1 1 1 1 .1 1 |
000000a0  31 20 31 20 31 20 31 20  31 20 31 20 31 20 31 20  |1 1 1 1 1 1 1 1 |
000000b0  0a 31 20 31 20 31 20 31  20 31 20 31 20 31 20 31  |.1 1 1 1 1 1 1 1|
000000c0  20 31 20 31 20 0a 31 20  31 20 31 20 31 20 31 20  | 1 1 .1 1 1 1 1 |
000000d0  31 20 31 20 31 20 31 20  31 20 0a                 |1 1 1 1 1 .|
000000db

不知道这是否正是您所需要的,但应该让您走上正轨。 也可能值得回顾coders/pnm.c文件中的WritePNMImage方法(ImageMagick-6 的同一文件)

解决方案

看来这个问题是通过删除以前从 Debian apt 存储库下载的问题包来解决的。 很难确定哪个是有问题的部分,但我删除了:

sudo apt remove graphicsmagick-libmagick-dev-compat imagemagick-6-common imagemagick-6.q16 imagemagick

接下来,我按照此处的说明从源代码构建了 ImageMagick。

解释

解决方案不仅仅是版本更改,这是可以理解的混淆,因为在源构建期间,我从仍在 Debian 存储库中的 ImageMagick 的 v6 升级到 v7。 但是,@emcconville 对 v6 和 v7 进行了测试,但没有重现我遇到的错误。 据推测,由于他参与了 ImageMagick 的开发,他使用的是从源代码构建的副本,而不是apt-get提供的副本。 因此,我们可以安全地假设问题出在 Debian 软件包之一中,或者是由受影响机器上的某些不正确的软件包组合引起的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM