本文介绍了加入2个PNG时,ImageMagick会保留自定义调色板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我需要加入2个PNG图像,16个调色板,保持颜色编号和顺序作为原件。I need to join 2 PNG images, with 16 color palette, keep colors number and order as originals.两个PNG使用相同的16色调色板。Both PNGs use the same 16 color palette.有一种方法可以创建具有所有颜色的4位索引PNG,按照确切的顺序,甚至在每个PNG中都未使用?There is a way to create 4 bit indexed PNG with all colors, in exact order, even unused in each PNG? 编辑更清晰:我有2张照片。 第一个是level-000.png:I have 2 pictures.The first is "level-000.png":标识为:Image: level-000.png Format: PNG (Portable Network Graphics) Mime type: image/png Class: PseudoClass Geometry: 144x144+0+0 Resolution: 28.35x28.35 Print size: 5.07937x5.07937 Units: PixelsPerCentimeter Type: Palette Endianess: Undefined Colorspace: sRGB Depth: 8-bit Channel depth: red: 8-bit green: 8-bit blue: 8-bit Channel statistics: Pixels: 20736 Red: min: 0 (0) max: 184 (0.721569) mean: 88.6151 (0.34751) standard deviation: 27.9329 (0.109541) kurtosis: 1.7675 skewness: 0.143857 Green: min: 0 (0) max: 199 (0.780392) mean: 68.8957 (0.270179) standard deviation: 22.7411 (0.0891808) kurtosis: 18.2722 skewness: 2.87959 Blue: min: 0 (0) max: 111 (0.435294) mean: 19.4671 (0.0763416) standard deviation: 22.1775 (0.0869706) kurtosis: 2.80475 skewness: 1.17593 Image statistics: Overall: min: 0 (0) max: 199 (0.780392) mean: 58.9926 (0.231344) standard deviation: 24.4216 (0.095771) kurtosis: 17.5446 skewness: 0.948025 Colors: 4 Histogram: 390: ( 0, 0, 0) #000000 black 10196: ( 67, 57, 0) #433900 srgb(67,57,0) 9770: (111, 79, 37) #6F4F25 srgb(111,79,37) 380: (184,199,111) #B8C76F srgb(184,199,111) Colormap entries: 16 Colormap: 0: ( 0, 0, 0) #000000 black 1: (255,255,255) #FFFFFF white 2: (104, 55, 43) #68372B srgb(104,55,43) 3: (112,164,178) #70A4B2 srgb(112,164,178) 4: (111, 61,134) #6F3D86 srgb(111,61,134) 5: ( 88,141, 67) #588D43 srgb(88,141,67) 6: ( 53, 40,121) #352879 srgb(53,40,121) 7: (184,199,111) #B8C76F srgb(184,199,111) 8: (111, 79, 37) #6F4F25 srgb(111,79,37) 9: ( 67, 57, 0) #433900 srgb(67,57,0) 10: (154,103, 89) #9A6759 srgb(154,103,89) 11: ( 68, 68, 68) #444444 srgb(68,68,68) 12: (108,108,108) #6C6C6C srgb(108,108,108) 13: (154,210,132) #9AD284 srgb(154,210,132) 14: (108, 94,181) #6C5EB5 srgb(108,94,181) 15: (149,149,149) #959595 srgb(149,149,149) Rendering intent: Perceptual Gamma: 0.454545 Chromaticity: red primary: (0.64,0.33) green primary: (0.3,0.6) blue primary: (0.15,0.06) white point: (0.3127,0.329) Background color: black Border color: srgb(223,223,223) Matte color: grey74 Transparent color: black Interlace: None Intensity: Undefined Compose: Over Page geometry: 144x144+0+0 Dispose: Undefined Iterations: 0 Compression: Zip Orientation: Undefined Properties: date:create: 2015-04-10T12:24:18+02:00 date:modify: 2015-04-09T22:33:29+02:00 png:bKGD: chunk was found (see Background color, above) png:IHDR.bit-depth-orig: 4 png:IHDR.bit_depth: 4 png:IHDR.color-type-orig: 3 png:IHDR.color_type: 3 (Indexed) png:IHDR.interlace_method: 0 (Not interlaced) png:IHDR.width,height: 144, 144 png:pHYs: x_res=2835, y_res=2835, units=1 png:PLTE.number_colors: 16 png:sRGB: intent=0 (Perceptual Intent) signature: 00d9489d55480d588c3329ab0fa844ed2a67eea06fd4dfa793503a36f9c4b160 Artifacts: filename: level-000.png verbose: true Tainted: False Filesize: 337B Number pixels: 20.7K Pixels per second: 0B User time: 0.000u Elapsed time: 0:01.000 Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-18第二张照片是scacchiera.png 。The second pic is "scacchiera.png".标识为:Image: scacchiera.png Format: PNG (Portable Network Graphics) Mime type: image/png Class: PseudoClass Geometry: 144x144+0+0 Resolution: 28.35x28.35 Print size: 5.07937x5.07937 Units: PixelsPerCentimeter Type: Palette Endianess: Undefined Colorspace: sRGB Depth: 8-bit Channel depth: red: 8-bit green: 8-bit blue: 8-bit Channel statistics: Pixels: 20736 Red: min: 67 (0.262745) max: 111 (0.435294) mean: 89 (0.34902) standard deviation: 22 (0.0862745) kurtosis: -2 skewness: -1.18433e-11 Green: min: 57 (0.223529) max: 79 (0.309804) mean: 68 (0.266667) standard deviation: 11 (0.0431373) kurtosis: -2 skewness: 7.03683e-11 Blue: min: 0 (0) max: 37 (0.145098) mean: 18.5 (0.072549) standard deviation: 18.5 (0.072549) kurtosis: -2 skewness: 0 Image statistics: Overall: min: 0 (0) max: 111 (0.435294) mean: 58.5 (0.229412) standard deviation: 17.7694 (0.0696837) kurtosis: 29.9398 skewness: -1.66976 Colors: 2 Histogram: 10368: ( 67, 57, 0) #433900 srgb(67,57,0) 10368: (111, 79, 37) #6F4F25 srgb(111,79,37) Colormap entries: 16 Colormap: 0: ( 0, 0, 0) #000000 black 1: (255,255,255) #FFFFFF white 2: (104, 55, 43) #68372B srgb(104,55,43) 3: (112,164,178) #70A4B2 srgb(112,164,178) 4: (111, 61,134) #6F3D86 srgb(111,61,134) 5: ( 88,141, 67) #588D43 srgb(88,141,67) 6: ( 53, 40,121) #352879 srgb(53,40,121) 7: (184,199,111) #B8C76F srgb(184,199,111) 8: (111, 79, 37) #6F4F25 srgb(111,79,37) 9: ( 67, 57, 0) #433900 srgb(67,57,0) 10: (154,103, 89) #9A6759 srgb(154,103,89) 11: ( 68, 68, 68) #444444 srgb(68,68,68) 12: (108,108,108) #6C6C6C srgb(108,108,108) 13: (154,210,132) #9AD284 srgb(154,210,132) 14: (108, 94,181) #6C5EB5 srgb(108,94,181) 15: (149,149,149) #959595 srgb(149,149,149) Rendering intent: Perceptual Gamma: 0.454545 Chromaticity: red primary: (0.64,0.33) green primary: (0.3,0.6) blue primary: (0.15,0.06) white point: (0.3127,0.329) Background color: white Border color: srgb(223,223,223) Matte color: grey74 Transparent color: black Interlace: None Intensity: Undefined Compose: Over Page geometry: 144x144+0+0 Dispose: Undefined Iterations: 0 Compression: Zip Orientation: Undefined Properties: date:create: 2015-04-10T20:46:55+02:00 date:modify: 2015-04-10T20:46:55+02:00 png:IHDR.bit-depth-orig: 4 png:IHDR.bit_depth: 4 png:IHDR.color-type-orig: 3 png:IHDR.color_type: 3 (Indexed) png:IHDR.interlace_method: 0 (Not interlaced) png:IHDR.width,height: 144, 144 png:pHYs: x_res=2835, y_res=2835, units=1 png:PLTE.number_colors: 16 png:sRGB: intent=0 (Perceptual Intent) signature: 8a0ca53e6e6f8e8fc4b141c7194b399ed1fc32473b174b6240addbb3f98864e5 Artifacts: filename: scacchiera.png verbose: true Tainted: False Filesize: 241B Number pixels: 20.7K Pixels per second: 0B User time: 0.000u Elapsed time: 0:01.000 Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-18如你所见,两张照片都有相同的颜色:As you can see, both pics have same colors: Colormap entries: 16 Colormap: 0: ( 0, 0, 0) #000000 black 1: (255,255,255) #FFFFFF white 2: (104, 55, 43) #68372B srgb(104,55,43) 3: (112,164,178) #70A4B2 srgb(112,164,178) 4: (111, 61,134) #6F3D86 srgb(111,61,134) 5: ( 88,141, 67) #588D43 srgb(88,141,67) 6: ( 53, 40,121) #352879 srgb(53,40,121) 7: (184,199,111) #B8C76F srgb(184,199,111) 8: (111, 79, 37) #6F4F25 srgb(111,79,37) 9: ( 67, 57, 0) #433900 srgb(67,57,0) 10: (154,103, 89) #9A6759 srgb(154,103,89) 11: ( 68, 68, 68) #444444 srgb(68,68,68) 12: (108,108,108) #6C6C6C srgb(108,108,108) 13: (154,210,132) #9AD284 srgb(154,210,132) 14: (108, 94,181) #6C5EB5 srgb(108,94,181) 15: (149,149,149) #959595 srgb(149,149,149)如果我加入他们convert -page 312x144+0+0 "scacchiera.png" -page +168+0 \ "level-000.png" -background black -layers flatten "joined.png"然后joined.png图片是:标识为:Image: joined.png Format: PNG (Portable Network Graphics) Mime type: image/png Class: PseudoClass Geometry: 312x144+0+0 Resolution: 28.35x28.35 Print size: 11.0053x5.07937 Units: PixelsPerCentimeter Type: Palette Endianess: Undefined Colorspace: sRGB Depth: 8-bit Channel depth: red: 8-bit green: 8-bit blue: 8-bit Channel statistics: Pixels: 44928 Red: min: 0 (0) max: 184 (0.721569) mean: 81.9762 (0.321475) standard deviation: 33.8163 (0.132613) kurtosis: 0.917842 skewness: -0.743586 Green: min: 0 (0) max: 199 (0.780392) mean: 63.1826 (0.247775) standard deviation: 25.0478 (0.0982265) kurtosis: 7.85041 skewness: 0.0804364 Blue: min: 0 (0) max: 111 (0.435294) mean: 17.5233 (0.0687188) standard deviation: 20.2675 (0.0794802) kurtosis: 1.51309 skewness: 0.876441 Image statistics: Overall: min: 0 (0) max: 199 (0.780392) mean: 54.2274 (0.212656) standard deviation: 26.9673 (0.105754) kurtosis: 7.87712 skewness: 0.327418 Colors: 4 Histogram: 3846: ( 0, 0, 0) #000000 black 20564: ( 67, 57, 0) #433900 srgb(67,57,0) 20138: (111, 79, 37) #6F4F25 srgb(111,79,37) 380: (184,199,111) #B8C76F srgb(184,199,111) Colormap entries: 4 Colormap: 0: ( 67, 57, 0) #433900 srgb(67,57,0) 1: (111, 79, 37) #6F4F25 srgb(111,79,37) 2: ( 0, 0, 0) #000000 black 3: (184,199,111) #B8C76F srgb(184,199,111) Rendering intent: Perceptual Gamma: 0.45455 Chromaticity: red primary: (0.64,0.33) green primary: (0.3,0.6) blue primary: (0.15,0.06) white point: (0.3127,0.329) Background color: black Border color: srgb(223,223,223) Matte color: grey74 Transparent color: black Interlace: None Intensity: Undefined Compose: Over Page geometry: 312x144+0+0 Dispose: Undefined Iterations: 0 Compression: Zip Orientation: Undefined Properties: date:create: 2015-04-12T15:13:11+02:00 date:modify: 2015-04-12T15:13:11+02:00 png:bKGD: chunk was found (see Background color, above) png:cHRM: chunk was found (see Chromaticity, above) png:gAMA: gamma=0.45454544 (See Gamma, above) png:IHDR.bit-depth-orig: 2 png:IHDR.bit_depth: 2 png:IHDR.color-type-orig: 3 png:IHDR.color_type: 3 (Indexed) png:IHDR.interlace_method: 0 (Not interlaced) png:IHDR.width,height: 312, 144 png:pHYs: x_res=2835, y_res=2835, units=1 png:PLTE.number_colors: 4 png:sRGB: intent=0 (Perceptual Intent) png:text: 2 tEXt/zTXt/iTXt chunks were found signature: 2049a10c0a2a73f864125d0ba93ccfc604a750667e3ba1d0fe8fe3be38a1cbea Artifacts: filename: joined.png verbose: true Tainted: False Filesize: 487B Number pixels: 44.9K Pixels per second: 4.493MB User time: 0.000u Elapsed time: 0:01.009 Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-18你可以看到调色板是与最初的完全不同。and you can see that palette is totally different from the initial one.图片在这里: www.dropbox.com/s/jdftk03rizeqcub/scacchiera.png www.dropbox。 com / s / 9c1fmav5qni8u2m / level-000.png www.dropbox.com/s/8hhd1zyzb31c4me/joined.pngwww.dropbox.com/s/jdftk03rizeqcub/scacchiera.pngwww.dropbox.com/s/9c1fmav5qni8u2m/level-000.pngwww.dropbox.com/s/8hhd1zyzb31c4me/joined.png问题是: 是否可以使用此调色板:The question is: is there a way to have ALWAYS this palette: Colormap entries: 16 Colormap: 0: ( 0, 0, 0) #000000 black 1: (255,255,255) #FFFFFF white 2: (104, 55, 43) #68372B srgb(104,55,43) 3: (112,164,178) #70A4B2 srgb(112,164,178) 4: (111, 61,134) #6F3D86 srgb(111,61,134) 5: ( 88,141, 67) #588D43 srgb(88,141,67) 6: ( 53, 40,121) #352879 srgb(53,40,121) 7: (184,199,111) #B8C76F srgb(184,199,111) 8: (111, 79, 37) #6F4F25 srgb(111,79,37) 9: ( 67, 57, 0) #433900 srgb(67,57,0) 10: (154,103, 89) #9A6759 srgb(154,103,89) 11: ( 68, 68, 68) #444444 srgb(68,68,68) 12: (108,108,108) #6C6C6C srgb(108,108,108) 13: (154,210,132) #9AD284 srgb(154,210,132) 14: (108, 94,181) #6C5EB5 srgb(108,94,181) 15: (149,149,149) #959595 srgb(149,149,149)这16种颜色的确切顺序是每个重新分配PNG的顺序吗?exactly with these 16 colors and in this order for each resluting PNG?推荐答案我已经为此做了一些工作,相信我可以实现你想要的......基本上,我允许ImageMagick进行重新制作和加入完全按照你的图像,然后我得到ImageMagick以便携式任何地图 PNM 格式输出NetPBM文件。然后我使用我编写的Perl编码器将 PNM 格式文件编码为PNG,以满足您对调色板的特定需求。因此,对于我从 PNM 文件读入的每个真彩色24位RGB像素,我通过做平方误差的总和来计算它最接近的那个调色板条目,并且然后输出一个调色板索引。I have worked on this some more, and believe I can achieve what you want... basically, I allow ImageMagick to do the repaging and joining of the images exactly as you had it, but then I get ImageMagick to output a NetPBM file in Portable Any Map PNM format. I then encode the PNM format file into a PNG using a Perl encoder I wrote to match your very specific needs as regards the palette. So, for every truecolour 24-bit RGB pixel I read in from the PNM file, I compute which palette entry it is nearest to by doing the sum of the square errors, and then outputting a single palette index. NetPBM 描述这里。 PNM 格式很容易解析,这就是我选择它的原因。 此处描述了这一点。The PNM format is really simple to parse and that's why I chose it. It is described here.所以,你的原始命令几乎是相同的,除了在 stdout 上输出 PNM 文件并读入Perl脚本 pnmtopng 然后生成您想要的 PNG 文件:So, your original command would be almost identical, except a PNM file is output on stdout and read into the Perl script pnmtopng which then makes the PNG file you wanted:convert -page 312x144+0+0 scacchiera.png -page +168+0 \ level-000.png -background black -layers flatten pnm:- | ./pnmtopng > out.png Perl脚本在这里:The Perl script is here:#!/usr/bin/perluse strict;use warnings;use Digest::CRC qw(crc32);use IO::Compress::Deflate qw(deflate $DeflateError) ;# Our beloved fixed palettemy @palette=( [0,0,0], [255,255,255], [104,55,43], [112,164,178], [111,61,134], [88,141,67], [53,40,121], [184,199,111], [111,79,37], [67,57,0], [154,103,89], [68,68,68], [108,108,108], [154,210,132], [108,94,181], [149,149,149] );################################################################################# Take chunk of PNG data as parameter, calculate its length & CRC, and output it################################################################################sub PNGoutputChunk(){ my $len=length($_[0])-4; my $crc = Digest::CRC->new(type=>"crc32"); $crc->add($_[0]); print pack('N',$len),$_[0],pack('N',$crc->digest);}################################################################################# Main################################################################################ # Read P6 PNM file from STDIN my $line = <STDIN>; chomp($line); if ($line ne "P6"){die "Expected P6 format PNM file"} # Read width and height from STDIN $line = <STDIN>; my ($width,$height) = ($line =~ /(\d+)\s+(\d+)/); print STDERR "DEBUG: width=$width, height=$height\n"; # Read MAX PNM value and ignore $line = <STDIN>; # Read entire remainder of PNM file my $expectedsize=$width * $height * 3; my $PNMdata; my $bytesRead = read(STDIN,$PNMdata,$expectedsize); if($bytesRead != $expectedsize){die "Unable to read PNM data"} # Output PNG header chunk printf "\x89PNG\x0d\x0a\x1a\x0a"; my $bitdepth=8; my $colortype=3; my $compressiontype=0; my $filtertype=0; my $interlacetype=0; # Output PNG IHDR chunk my $IHDR='IHDR'; $IHDR .= pack 'N',$width; $IHDR .= pack 'N',$height; $IHDR .= pack 'c',$bitdepth; $IHDR .= pack 'c',$colortype; $IHDR .= pack 'c',$compressiontype; $IHDR .= pack 'c',$filtertype; $IHDR .= pack 'c',$interlacetype; &PNGoutputChunk($IHDR); # Output PNG PLTE (palette) my $PLTE='PLTE'; for(my $i=0;$i<scalar @palette;$i++){ $PLTE .= sprintf('%c',$palette[$i][0]); # Red $PLTE .= sprintf('%c',$palette[$i][1]); # Green $PLTE .= sprintf('%c',$palette[$i][2]); # Blue } &PNGoutputChunk($PLTE); # Output PNG IDAT chunk # RFC-1950 zlib compression my $raw; # Go through PNM data, and for each RGB pixel, find nearest palette entry my @PNMvalues = unpack("C*",$PNMdata); print STDERR "Unpacked ",scalar @PNMvalues," from raw\n"; for(my $pixel=0;$pixel<(scalar @PNMvalues)/3;$pixel++){ # Output filter type byte (0) at start of each scanline if($pixel%$width==0){$raw .= "\x00";} my $r=$PNMvalues[(3*$pixel)]; # Red PNM value my $g=$PNMvalues[(3*$pixel)+1]; # Green PNM value my $b=$PNMvalues[(3*$pixel)+2]; # Blue PNM value my $nearest=0; my $distmin=(255*255)+(255*255)+(255*255); # Couldn't get further # Go through all palette entries to find nearest to this RGB for(my $pe=0;$pe<scalar @palette;$pe++){ my $pr=$palette[$pe][0]; # Red palette value my $pg=$palette[$pe][1]; # Green palette value my $pb=$palette[$pe][2]; # Blue palette value my $dist = ($pr-$r)*($pr-$r) + ($pg-$g)*($pg-$g) + ($pb-$b)*($pb-$b); if($dist<$distmin){ $distmin=$dist; $nearest=$pe; } } $raw .= sprintf "%c",$nearest; print STDERR "Pixel: $pixel, r=$r, g=$g, b=$b. Chose palette entry $nearest\n"; } print STDERR "Length of raw: ",length($raw); my $deflated; my $status = deflate \$raw => \$deflated or die "deflate failed: $DeflateError\n"; my $IDAT="IDAT" . $deflated; &PNGoutputChunk($IDAT); # Output PNG IEND chunk &PNGoutputChunk('IEND');结果如下: 这篇关于加入2个PNG时,ImageMagick会保留自定义调色板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 05-18 10:17