Magick ++``depth''与``convert -depth''的行为不同 [英] Magick++ ``depth`` does not behave the same as ``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
不知道这是否正是您所需要的,但是应该使您步入正轨.也可能值得回顾 I discovered via my previous question that Using: I get an output image which, upon inspection, shows a 1-bit color depth:
Using the code: Compiled using the command: Produces the output:
I have run this with the same result on on:coders/pnm.c
文件(与ImageMagick-6相同). /p>depth
appears to work differently when I use it in ImageMagick's convert
vs Magick++
.CLI version and result
$ convert /foo/bar.ppm -depth 1 /foo/out.ppm
$ identify /foo/out.ppm
out.ppm PPM (blah blah) 1-bit sRGB (blah blah)
C++ version and result
#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)
Hardware
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屋!