ImageMagick で PNM 画像

PNM 形式は、ビットマップ画像の RGB 値をテキスト文字で表現できます。
ちょっとした実験用画像を作るのに重宝しますし、画像の RGB 値を確認する時にも便利です。


# 画像作成

以下の要件で画像を作って見ます。

- RGB画像 => P3
- 画像サイズ width:2 x height:2 => 2 2
- 色階調 {0,1} の2階調で max が 1 => 1
- 赤(1 0 0)、黄色(1 1 0)、緑(0 1 0)、青(0 0 1)
- 2x2 画像は小さすぎるので、200x200 に拡大。
- PNG 画像として保存

```
% cat opposite.pnm
P3
2 2
1
1 0 0  1 1 0
0 1 0  0 0 1
% convert opposite.pnm -scale 200x200 opposite.png
```

![opposite.png](https://qiita-image-store.s3.amazonaws.com/0/1798/c81baafd-861e-d4ae-4c72-2de7813edf7d.png)

改行をサボれるので、１行コマンドにも出来ます。

```
echo "P3 2 2 1 1 0 0 1 1 0 0 1 0 0 0 1" | convert - -scale 200x200 opposite.png 
```

# 画像ダンプ

逆に PNG を PNM に戻す事も出来ます。

```
% convert opposite.png -scale 2x2 pnm:-
P6
2 2
255
�����%
```

BINARY 形式で出てしまいました。-compress none オプションで ASCII を出力できます。

```
% convert opposite.png -scale 2x2 -compress none pnm:-
P3
2 2
255
255 0 0  255 255 0
0 255 0  0 0 255
```

256階調の赤(255 0 0)、黄色(255 255 0)、緑(0 255 0）、青(0 0 255)ですので実質的に元に戻っています。

# PNM の種類

PNM はいくつかのフォーマットをまとめた総称です。PNM ファミリーと呼称されます。テキストかバイナリか、色付きか色なしか等で種類があります。

| マジックナンバー | フォーマット名 | データ表現 | 画像表現 |
|:--|:--|:--|:--|
| P1 | PBM | ASCII | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/8e069f16-c1c4-d9b5-f371-e705d9520048.png) 白黒画像  |
| P2 | PGM | ASCII | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/4b965245-823d-d6b0-7781-671e2d5ba02e.png) グレー画像  |
| P3 | PPM | ASCII |  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/a2a0b0d1-7d0c-9f6e-24af-1cec427177de.png) カラー画像 |
| P4 | PBM | Binary | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/8e069f16-c1c4-d9b5-f371-e705d9520048.png)  白黒画像  |
| P5 | PGM | Binary |![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/4b965245-823d-d6b0-7781-671e2d5ba02e.png) グレー画像  |
| P6 | PPM | Binary |  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/5e5317f4-651f-b32a-f107-356927b1a270.png) カラー画像 |
| P7 | PAM | Binary |  ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/d251b3bc-ec58-8981-908b-01c002255726.png) アルファ付きカラー画像 |
| Pf | PFM | Binary | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/4b965245-823d-d6b0-7781-671e2d5ba02e.png) 浮動小数点形式グレースケール画像 |
| PF | PFM | Binary | ![image.png](https://qiita-image-store.s3.amazonaws.com/0/1798/51b2d0db-c2fa-453c-c52b-f1ff70a8cda5.png) 浮動小数点形式カラー画像 |

P1(白黒), P2(グレースケール), P3(カラー) の実例を示します。

## PBM (P1) 白黒

```
% cat batsu.pbm
P1
5 5
1 0 0 0 1
0 1 0 1 0
0 0 1 0 0
0 1 0 1 0
1 0 0 0 1
% convert batsu.pbm -size 100x100 batsu-P1.png
```
|batsu-P1.png|
|---|
|![batsu-P1.png](https://qiita-image-store.s3.amazonaws.com/0/1798/167ecb05-aea1-f143-8ca3-5e765dc3fa19.png)|

ちなみに、**1が黒で０が白**です。

## PGM: (P2) グレースケール

```
% cat batsu.pgm
P2
5 5
4
4 0 0 0 4
0 3 0 3 0
0 0 2 0 0
0 3 0 3 0
4 0 0 0 4
% convert batsu.pgm -scale 100x100 batsu-P2.png
```

|batsu-P2.png|
|---|
|![batsu-P2.png](https://qiita-image-store.s3.amazonaws.com/0/1798/3092618e-bcde-2a91-cc64-515b00e8b2c0.png)|

こちらは 0 が黒で 最大値(この例では4)が白です。

## PPM: (P3) カラー

```
% cat batsu.ppm 
P3
5 5
4
4 0 0  0 0 0  0 0 0  0 0 0  0 0 4
0 0 0  3 0 0  0 0 0  0 0 3  0 0 0
0 0 0  0 0 0  2 2 2  0 0 0  0 0 0
0 0 0  0 3 0  0 0 0  3 3 0  0 0 0
0 4 0  0 0 0  0 0 0  0 0 0  4 4 0
% convert batsu.ppm -scale 100x100 batsu-P3.png
```

|batsu-P3.png|
|---|
|![batsu-P3.png](https://qiita-image-store.s3.amazonaws.com/0/1798/23edef6f-a8e3-6dcc-90e9-fa1813d3a452.png)|

## 拡張

P7(PAM)、Pf,PF(PFM) は狭義の PNM ファミリーに入らず、拡張フォーマット扱いされるようです。(要出典)
PAM は TUPLTYPE の後ろに RGB 等の色コンポーネント文字列をつける事で様々な色表現が使えます。公式仕様にはないのですが、ImageMagick は CMYK にも対応しています。

# 注意

## 最後の改行 (2021年12月9日追記)

- Unable to read plain encoded PNM files #4546
   - https://github.com/ImageMagick/ImageMagick/issues/4546

最後が改行で終わらない PNM 画像は ImageMagick で処理できません。
なお、Netbpm でも失敗します。macOS の画像プレビューでも失敗します。

echo に -n (改行なし) をつけると確認できます。

```shell
% echo -n 'P3 2 2 1 1 0 0  1 1 0  0 1 0  0 0 1' | convert - output.png
convert: unable to read image data `/var/(略)' @ error/pnm.c/ReadPNMImage/1442.
convert: no images defined `opposite.png' @ error/convert.c/ConvertImageCommand/3322.
```

Adobe Phoroshop CC 2020 や GIMP 2.10 はこれを読み取れます。(macOS 版で確認しました)

# 参考

- https://www.imagemagick.org/script/formats.php

- http://netpbm.sourceforge.net/doc/pnm.html

- http://netpbm.sourceforge.net/doc/pbm.html
- http://netpbm.sourceforge.net/doc/pgm.html
- http://netpbm.sourceforge.net/doc/ppm.html

- http://netpbm.sourceforge.net/doc/pam.html
- http://netpbm.sourceforge.net/doc/pfm.html