英文:
How to convert an 8bpp bitmap to 1bpp bitmap in Python
问题
以下是您提供的代码的翻译部分:
我有一些代码,用于创建灰度(8bpp)图像,但我需要创建1bpp(二进制)图像以供打印机使用。我在这里看到了两篇帖子,但不理解它们是如何解决问题的。
https://stackoverflow.com/questions/21067028/cant-format-bmp-image-data-to-1-bit-per-pixel-in-pil
我已经安装了Pillow,但按照我所阅读的所有教程,都要从PIL中导入Image。
我有一个名为conv_to_1bpp的方法,将所有值为255的像素设置为1,但这仍然生成8bpp图像。
**代码**
```python
from PIL import Image
import numpy as np
import os
import sys
import struct
class BmpMaker:
def __init__(self):
self.ffp = None
self.img_width = None
self.img_height = None
self.ws_activation = None
self.bpp = None
def make_image(self, img_width, img_height, ws_activation):
"""创建位图。"""
self.ffp = None
self.img_width = img_width
self.img_height = img_height
self.ws_activation = ws_activation
# 创建新的黑色图像 - L模式用于黑白
img = Image.new('L', (img_width, img_height))
# 转换为Numpy数组以便于处理
na = np.array(img)
# 设置白色空白激活的行数
white_rows = ws_activation
# 创建白色线条
na[0:white_rows, 0:999] = 255
# 从Numpy数组中恢复为PIL图像并保存
self.ffp = self.make_img_title(img_width, img_height, ws_activation)
Image.fromarray(na).save(self.ffp)
self.bpp = self.get_bitdepth()
return self.ffp
def make_img_title(self, img_width, img_height, ws_activation):
if ws_activation == 0:
mystr = f"{img_height}x{img_width}"
elif ws_activation is not None:
mystr = f"{ws_activation}_{img_height}x{img_width}"
self.ffp = os.path.join(os.getcwd(), mystr + ".bmp")
print("img_ffp : ", self.ffp)
return self.ffp
def get_bitdepth(self):
# 读取前100个字节
with open(self.ffp, 'rb') as f:
BMP = f.read(100)
if BMP[0:2] != b'BM':
sys.exit('错误:不正确的BMP签名')
# 获取BITMAPINFOHEADER大小 - https://en.wikipedia.org/wiki/BMP_file_format
BITMAPINFOHEADERSIZE = struct.unpack('<i', BMP[14:18])[0]
okSizes = [40, 52, 56, 108, 124]
if BITMAPINFOHEADERSIZE not in okSizes:
sys.exit(f'错误:BITMAPINFOHEADER大小为{BITMAPINFOHEADERSIZE},期望其中之一{okSizes}')
# 获取每像素位数
self.bpp = struct.unpack('<H', BMP[28:30])[0]
print(f'bpp:{self.bpp}')
return self.bpp
def get_img_bitdepth(self, img):
# 读取前100个字节
with open(img, 'rb') as f:
BMP = f.read(100)
if BMP[0:2] != b'BM':
sys.exit('错误:不正确的BMP签名')
# 获取BITMAPINFOHEADER大小 - https://en.wikipedia.org/wiki/BMP_file_format
BITMAPINFOHEADERSIZE = struct.unpack('<i', BMP[14:18])[0]
okSizes = [40, 52, 56, 108, 124]
if BITMAPINFOHEADERSIZE not in okSizes:
sys.exit(f'错误:BITMAPINFOHEADER大小为{BITMAPINFOHEADERSIZE},期望其中之一{okSizes}')
# 获取每像素位数
img_bpp = struct.unpack('<H', BMP[28:30])[0]
print(f'bpp:{img_bpp}')
return img_bpp
def conv_to_1bpp(self):
img = Image.open(self.ffp)
arr = np.array(img)
# 将所有值等于255的索引处的像素设置为1。
arr[arr == 255] = 1
print('\n' * 3, arr)
Image.fromarray(arr).save("my_img.bmp")
print(self.get_img_bitdepth("my_img.bmp"))
if __name__ == "__main__":
import PIL
print('Pillow版本:', PIL.__version__)
bm = BmpMaker()
base_image = bm.make_image(1000, 8, 5)
print("位图ffp:", bm.ffp)
print("位图位深度:", bm.bpp)
bm.conv_to_1bpp()
希望这能帮助您理解代码。如果您需要进一步的帮助,请随时告诉我。
英文:
I have some code which is fine for creating greyscale (8bpp) images but I need to create 1bpp (binary) also for a printer. I have seen 2 posts here but cannot understand how they fix the issue.
https://stackoverflow.com/questions/21067028/cant-format-bmp-image-data-to-1-bit-per-pixel-in-pil
I have pillow installed but call it using PIL as all the tutorials I have read seem to say to import Image from PIL.
I have a method called conv_to_1bpp which sets anything at 255 equal to 1, this is still making 8bpp images though.
Code
from PIL import Image
import numpy as np
import os
import sys
import struct
class BmpMaker:
def __init__(self):
self.ffp = None
self.img_width = None
self.img_height = None
self.ws_activation = None
self.bpp = None
def make_image(self, img_width, img_height, ws_activation):
"""Creates a bitmap."""
self.ffp = None
self.img_width = img_width
self.img_height = img_height
self.ws_activation = ws_activation
# Create new black image - L mode for b/w
img = Image.new('L', (img_width, img_height))
# Convert to Numpy array for easy processing
na = np.array(img)
# set the amount of white space activation
white_rows = ws_activation
# make white lines
na[0:white_rows, 0:999] = 255
# Revert to PIL Image from Numpy array and save
self.ffp = self.make_img_title(img_width, img_height, ws_activation)
Image.fromarray(na).save(self.ffp)
self.bpp = self.get_bitdepth()
return self.ffp
def make_img_title(self, img_width, img_height, ws_activation):
if ws_activation == 0:
mystr = f"{img_height}x{img_width}"
elif ws_activation is not None:
mystr = f"{ws_activation}_{img_height}x{img_width}"
self.ffp = os.path.join(os.getcwd(), mystr + ".bmp")
print("img_ffp : ", self.ffp)
return self.ffp
def get_bitdepth(self):
# Read first 100 bytes
with open(self.ffp, 'rb') as f:
BMP = f.read(100)
if BMP[0:2] != b'BM':
sys.exit('ERROR: Incorrect BMP signature')
# Get BITMAPINFOHEADER size - https://en.wikipedia.org/wiki/BMP_file_format
BITMAPINFOHEADERSIZE = struct.unpack('<i', BMP[14:18])[0]
okSizes = [40, 52, 56, 108, 124]
if BITMAPINFOHEADERSIZE not in okSizes:
sys.exit(f'ERROR: BITMAPINFOHEADER size was {BITMAPINFOHEADERSIZE},'
f' expected one of {okSizes}')
# Get bits per pixel
self.bpp = struct.unpack('<H', BMP[28:30])[0]
print(f'bbp: {self.bpp}')
return self.bpp
def get_img_bitdepth(self, img):
# Read first 100 bytes
with open(img, 'rb') as f:
BMP = f.read(100)
if BMP[0:2] != b'BM':
sys.exit('ERROR: Incorrect BMP signature')
# Get BITMAPINFOHEADER size - https://en.wikipedia.org/wiki/BMP_file_format
BITMAPINFOHEADERSIZE = struct.unpack('<i', BMP[14:18])[0]
okSizes = [40, 52, 56, 108, 124]
if BITMAPINFOHEADERSIZE not in okSizes:
sys.exit(f'ERROR: BITMAPINFOHEADER size was {BITMAPINFOHEADERSIZE},'
f' expected one of {okSizes}')
# Get bits per pixel
img_bpp = struct.unpack('<H', BMP[28:30])[0]
print(f'bbp: {img_bpp}')
return img_bpp
def conv_to_1bpp(self):
img = Image.open(self.ffp)
arr = np.array(img)
#print(arr)
# Set all values at indices where the array equals 255 to 1.
arr[arr==255] = 1
print('\n'*3, arr)
Image.fromarray(arr).save("my_img.bmp")
print(self.get_img_bitdepth("my_img.bmp"))
if __name__ == "__main__":
import PIL
print('Pillow Version:', PIL.__version__)
bm = BmpMaker()
base_image = bm.make_image(1000, 8, 5)
print("bitmap ffp: ", bm.ffp)
print("bitmap bitdepth : ", bm.bpp)
bm.conv_to_1bpp()
答案1
得分: 1
当创建初始图像时,使用模式 '1' 而不是 'L'。
# 创建新的黑白图像 - 使用 '1' 模式进行二值化
img = Image.new('1', (img_width, img_height))
英文:
when creating the initial image use mode '1' instead of 'L'
# Create new black image - L mode for b/w, '1' for binary
img = Image.new('1', (img_width, img_height))
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论