问题
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++
回答1:
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).
回答2:
Solution
It appears that this problem was solved by removing problem packages previously downloaded from the Debian apt repository. It is difficult to nail down which was the offending part, but I removed:
sudo apt remove graphicsmagick-libmagick-dev-compat imagemagick-6-common imagemagick-6.q16 imagemagick
Next, I built ImageMagick from source, following the directions here.
Explanation
The solution was not simply a version change, which would be an understandable confusion since during the source build, I upgraded from v6 of ImageMagick still in the Debian repository to v7. However, tests by @emcconville were performed on both v6 and v7 without reproducing the errors I experienced. Presumably, since he is involved with ImageMagick development, he uses a copy built from source rather than what is available from apt-get
. Therefore, we can safely assume that the problem is either in one of the Debian packages or caused by some incorrect combination of packages on the affected machine.
来源:https://stackoverflow.com/questions/63141968/magick-depth-does-not-behave-the-same-as-convert-depth