Magick ++``depth''与``convert -depth''的行为不同 [英] Magick++ ``depth`` does not behave the same as ``convert -depth``

查看:106
本文介绍了Magick ++``depth''与``convert -depth''的行为不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过我以前的问题发现,当我在ImageMagick的convert中使用depth时,它的工作方式有所不同.与Magick++.

CLI版本和结果

使用:

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

我得到一张输出图像,经检查,该图像显示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`
 

产生输出:

 $ identify /foo/out.ppm

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

硬件

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

  • Raspberry Pi-Raspbian 10(破坏者)
  • 笔记本电脑-Ubuntu 18.04(仿生海狸)

软件(在RPi上)

 $ 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 repos速度很慢,但是(据我所知)源代码中没有任何变化会影响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

不知道这是否正是您所需要的,但是应该使您步入正轨.也可能值得回顾WritePNMImage方法.rel ="nofollow noreferrer"> coders/pnm.c 文件(与ImageMagick-6相同). /p>

I discovered via my previous question that depth appears to work differently when I use it in ImageMagick's convert vs Magick++.

CLI version and result

Using:

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

I get an output image which, upon inspection, shows a 1-bit color depth:

$ identify /foo/out.ppm

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

C++ version and result

Using the code:

#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;
}

Compiled using the command:

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

Produces the output:

$ identify /foo/out.ppm

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

Hardware

I have run this with the same result on on:

  • Raspberry Pi - Raspbian 10 (buster)
  • Laptop - Ubuntu 18.04 (bionic beaver)

Software (on the RPi)

$ 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]

The Picture

I've tested with multiple input files with sRGB type. I convert everything to NetBPM format before starting my test e.g.:

convert yourimage.jpg /foo/bar.ppm

The Question

Why is the C++ different from the Bash version? They should be linking to the exact same code in the background. The input value for depth does not need to be a special type (Magick::Image.depth takes size_t). Is there something in my installation which is messing this up? I know most of it is based on ImageMagick v6 because debian repos are notoriously slow, but nothing has changed (to my knowledge) in the source code which should effect the depth.

What else doesn't work?

Quantization

Adding:

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

to the code should also be a method which reduces the color depth. Again, this results in an 8-bit image in C++.

Monochrome

This results in an 8-bit image in both CLI and C++

解决方案

Closest solution I can think of is to user the "PBM" format.

Generating a test image with the following.

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

Just using the Magick::Image.magick method.

#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;
}

We get the following file structure...

$ 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

If we want the ASCII representation of the binary data, just disable the compression.

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

Which would yield the following...

$ 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

Don't know if that's exactly which you need, but should get you on track. Also might be worth reviewing WritePNMImage method in coders/pnm.c file (same file for ImageMagick-6).

这篇关于Magick ++``depth''与``convert -depth''的行为不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆