使用 PIL 将图像从 PNG 转换为 PBM(只有 1 和 0)

Image Conversion from PNG to PBM (solely 1s and 0s) using PIL

我正在尝试将 PNG 图像转换为 PBM 文件。这些 PNG 文件是黑白的,我需要生成的 PBM 是仅包含 1 和 0 的 P1 位图。到目前为止,我最接近的是以下代码:

img = Image.open("test part stl00000.png")
img = img.convert('1')
img.save("new.pbm")

但是,这不会产生所需的输出。当我在 VS 代码中打开输出文件时,我在菱形框中看到一堆问号以及红色空框(不允许我在此处附加图像)。当我在记事本中打开文件时,它是空格,上面有双点。有谁知道为什么我的输出不是 1s 和 0s,行数和列数对应于我正在转换的 PNG 的大小?

编辑: 我看到 post 说我不应该期望看到 1 和 0 的 ASCII 数字,但是当我在 PBM 中打开它时查看器我会看到我开始的图像。这是正确的,但不幸的是,我需要我正在处理的项目的 ASCII 数字。有谁知道我如何进行转换,以便最终得到直接的 1 和 0,以便我能够对其进行操作?

PIL 不支持 PBM 的 ASCII 格式,但是在它的帮助下自己做起来相当容易,因为 PBM file format is so simple. The code below is based on to the question

注意,如果您只需要 ASCII 数字,那么这就是写入输出文件的 data 列表中的最终结果。

from pathlib import Path
from PIL import Image

ASCII_BITS = '0', '1'
imagepath = Path('peace_sign.png')

img = Image.open(imagepath).convert('1')  # Convert image to bitmap.
width, height = img.size

# Convert image data to a list of ASCII bits.
data = [ASCII_BITS[bool(val)] for val in img.getdata()]
# Convert that to 2D list (list of character lists)
data = [data[offset: offset+width] for offset in range(0, width*height, width)]

with open(f'{imagepath.stem}.pbm', 'w') as file:
    file.write('P1\n')
    file.write(f'# Conversion of {imagepath} to PBM format\n')
    file.write(f'{width} {height}\n')
    for row in data:
        file.write(' '.join(row) + '\n')

print('fini')

这张测试图片:

生成了具有以下内容的 PBM 格式文件:

Numpy 可以通过 np.savetxt() 非常简单地为您保存数组,如下所示:

#!/usr/bin/env python3

import numpy as np
from PIL import Image

# Load image and convert to '1' mode
im = Image.open('image.png').convert('1')

# Make Numpy array from image
na = np.array(im)

# Save array
np.savetxt('image.pbm', na, fmt='%d')

如果您想要完整的 PBM header,请将上面的最后一行替换为以下三行:

# Use this to put NetPBM header on as well
# https://en.wikipedia.org/wiki/Netpbm#PBM_example

with open('image.pbm','w') as f:
    f.write(f'P1\n{im.width} {im.height}\n')
    np.savetxt(f, na, fmt='%d')