如何使用 color_type=3 和 bit_depth=1 创建 PNG 图像

How to create PNG image with color_type=3 and bit_depth=1

来源是 RGBA PNG 图像(color_type=6 和 bit_depth=8)。

我需要一张带有索引颜色和 2 个调色板项目的图像(color_type=3,bit_depth=1)。

我尝试使用 ImageMagick,但只能达到 1 位灰度图像(color_type=0,bit_depth=1)或 2 位索引彩色图像(color_type=3, bit_depth=2) 其中只使用了 2 种颜色。

根据 PNG 规范,这样的图片是可以的,但是如何创建呢?

这是我要转换的图像:

"convert input.png -type palette -depth 1 output.png"的结果:

"convert input.png -type palette -depth 1 -colors 2 output.png"

的结果

两个结果都有 bit_depth=2,但第二个结果只使用了 4 种可能的 2 种颜色。

我想你需要的命令是这样的:

convert input.png -type palette -depth 1 output.png

如果没有,请 post 您的输入图像并说 how/where 您找到了您引用的 color_typebit_depth 字段。

Exiftool 告诉我这个:

ExifTool Version Number         : 9.76
File Name                       : output.png
Directory                       : .
File Size                       : 2.3 kB
File Modification Date/Time     : 2015:01:10 19:20:33+00:00
File Access Date/Time           : 2015:01:10 19:21:46+00:00
File Inode Change Date/Time     : 2015:01:10 19:20:33+00:00
File Permissions                : rw-r--r--
File Type                       : PNG
MIME Type                       : image/png
Image Width                     : 640
Image Height                    : 427
Bit Depth                       : 1
Color Type                      : Grayscale
Compression                     : Deflate/Inflate
Filter                          : Adaptive
Interlace                       : Noninterlaced
Gamma                           : 2.2
Background Color                : 1
Datecreate                      : 2015-01-10T10:21:30+00:00
Datemodify                      : 2015-01-10T10:21:30+00:00
Image Size                      : 640x427

ImageMagick identify 告诉我这个:

Image: output.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 640x427+0+0
  Units: Undefined
  Type: Bilevel
  Base type: Bilevel
  Endianess: Undefined
  Colorspace: Gray
  Depth: 8/1-bit
  Channel depth:
    gray: 1-bit
  Channel statistics:
    Pixels: 273280
    Gray:
      min: 0 (0)
      max: 255 (1)
      mean: 1.90168 (0.00745755)
      standard deviation: 21.9388 (0.0860345)
      kurtosis: 129.1
      skewness: 11.4499
  Colors: 2
  Histogram:
    271242: (  0,  0,  0) #000000 gray(0)
      2038: (255,255,255) #FFFFFF gray(255)
  Colormap entries: 2
  Colormap:
         0: (  0,  0,  0) #000000 gray(0)
         1: (255,255,255) #FFFFFF gray(255)
  Rendering intent: Undefined
  Gamma: 0.45455
  Background color: gray(255)
  Border color: gray(223)
  Matte color: gray(189)
  Transparent color: gray(0)
  Interlace: None
  Intensity: Undefined
  Compose: Over
  Page geometry: 640x427+0+0
  Dispose: Undefined
  Iterations: 0
  Compression: Zip
  Orientation: Undefined
  Properties:
    date:create: 2015-01-10T19:20:33+00:00
    date:modify: 2015-01-10T19:20:33+00:00
    png:bKGD: chunk was found (see Background color, above)
    png:gAMA: gamma=0.45455 (See Gamma, above)
    png:IHDR.bit-depth-orig: 1
    png:IHDR.bit_depth: 1
    png:IHDR.color-type-orig: 0
    png:IHDR.color_type: 0 (Grayscale)
    png:IHDR.interlace_method: 0 (Not interlaced)
    png:IHDR.width,height: 640, 427
    png:text: 2 tEXt/zTXt/iTXt chunks were found
    signature: 3e08d7fea7bc7aeb0659ac2e2696084083d35ce30b0e3075dc561ad94259eaec
  Artifacts:
    filename: output.png
    verbose: true
  Tainted: True
  Filesize: 2.33KB
  Number pixels: 273K
  Pixels per second: 27.33MB
  User time: 0.000u
  Elapsed time: 0:01.009
  Version: ImageMagick 6.8.9-8 Q16 x86_64 2014-11-10 http://www.imagemagick.org

convert input.png -background white -type palette -depth 1 -colors 2 output.png

适合我。

(为什么 -depth=1 不够?不知道。)

顺便说一句,tweakpng 工具对检查这类事情很有用。

更新:如果图像有透明度,您可以通过明确删除它来玩得更安全:

convert input.png -background white -flatten -type palette -depth 1 -colors 2 output.png

(您可以根据自己的喜好替换white

使用以下 3 个之一,在输出文件中从最少到最多的辅助标签排序:

convert -colors 2 -define png:include-chunk=none -verbose input.png output.png

convert -colors 2 -define png:exclude-chunk=bkgd -verbose input.png output.png

convert -colors 2 -background #000000 -verbose input.png output.png

这个问题的根源是 ImageMagick 默认情况下用白色标记图像 background color (bKGD) PNG chunk (unnecessarily I'd say), and then adds this color to the palette if it's not already there, even if the image has no pixels of that color. Your particular image doesn't have white after converting to 2-color, so the unneeded background color tag becomes a 3rd color and it can no longer be saved as a 1-bit indexed color image. See also this from the author of IM

其他人未能重现该问题的原因可能是他们测试了两种颜色之一恰好是白色的图像。

带有 -define png:include-chunk=none 的第一个选项通过根本不输出任何辅助 PNG 块(例如 bKGD、gAMA、cHRM、tEXt、tIME)来避免该问题。喜欢pngcrush -rem alla。对于一个不那么混乱的文件,我更喜欢这个(没有它,即使它们不在输入文件中,IM 也会添加其中的一些)。 注意: 还有一个简单的 -strip 选项 should avoid most of these,但是从 v6.9.3 开始,由于一个错误,它不会削减 bKGD。

第二个 -define png:exclude-chunk=bkgd 仅删除有问题的背景块。

带有 -background #000000 的第三个选项保留所有辅助 PNG 块,包括 bKGD,但将其设置为黑色,这是图像中存在的两种颜色之一,因此它仍然可以是 1 位。为既非白色也非黑色的图像调整颜色。

请注意,对于所有这些,我都包括 -verbose 开关。不要过于冗长;只是从零到两行状态输出,如果图像保持 2 色,你会注意到一个“2c”,如果不是,你会注意到一个“3c”。它还会告诉您调色板减少是否有损。它还为大多数图像输出“8 位 sRGB”,即使是每像素少于 8 位的调色板;这不是您对另一个答案 @johnfound 的评论中的错误,这不是指每像素位数,而是指每颜色位数组件。对于(罕见的)深色图像,它可以超过 8 位。