Ok, đây là một cái gì đó để bắt đầu. Vì tôi không biết cụ thể định dạng nào là tệp BMP của bạn nên tôi chỉ xử lý một trường hợp cụ thể của BMP với kênh alpha đầy đủ mà tôi đã có. Các loại BMP tôi đang xử lý ở đây có thể thu được bằng cách chuyển đổi, ví dụ, PNG với alpha sang BMP bằng cách sử dụng ImageMagick. Điều này sẽ tạo ra những gì được gọi là "BITMAPV5". Với mô tả của bạn, bạn không có BitmapV5 (vì PIL sẽ không mở được nó), vì vậy chúng tôi sẽ cần lặp lại với các cuộc thảo luận để giải quyết trường hợp cụ thể của bạn.
Vì vậy, bạn cần bộ giải mã tệp mới hoặc bản vá BmpImagePlugin.py
được vá. Làm thế nào để làm việc trước đây được mô tả trong hướng dẫn sử dụng của PIL. Đối với sau này bạn rõ ràng sẽ cần phải gửi một bản vá và hy vọng để có được nó vào phiên bản kế tiếp PIL. Trọng tâm của tôi là về việc tạo ra một bộ giải mã mới:
from PIL import ImageFile, BmpImagePlugin
_i16, _i32 = BmpImagePlugin.i16, BmpImagePlugin.i32
class BmpAlphaImageFile(ImageFile.ImageFile):
format = "BMP+Alpha"
format_description = "BMP with full alpha channel"
def _open(self):
s = self.fp.read(14)
if s[:2] != 'BM':
raise SyntaxError("Not a BMP file")
offset = _i32(s[10:])
self._read_bitmap(offset)
def _read_bitmap(self, offset):
s = self.fp.read(4)
s += ImageFile._safe_read(self.fp, _i32(s) - 4)
if len(s) not in (40, 108, 124):
# Only accept BMP v3, v4, and v5.
raise IOError("Unsupported BMP header type (%d)" % len(s))
bpp = _i16(s[14:])
if bpp != 32:
# Only accept BMP with alpha.
raise IOError("Unsupported BMP pixel depth (%d)" % bpp)
compression = _i32(s[16:])
if compression == 3:
# BI_BITFIELDS compression
mask = (_i32(self.fp.read(4)), _i32(self.fp.read(4)),
_i32(self.fp.read(4)), _i32(self.fp.read(4)))
# XXX Handle mask.
elif compression != 0:
# Only accept uncompressed BMP.
raise IOError("Unsupported BMP compression (%d)" % compression)
self.mode, rawmode = 'RGBA', 'BGRA'
self.size = (_i32(s[4:]), _i32(s[8:]))
direction = -1
if s[11] == '\xff':
# upside-down storage
self.size = self.size[0], 2**32 - self.size[1]
direction = 0
self.info["compression"] = compression
# data descriptor
self.tile = [("raw", (0, 0) + self.size, offset,
(rawmode, 0, direction))]
Để sử dụng đúng cách này, cách kinh điển được cho là để thực hiện:
from PIL import Image
Image.register_open(BmpAlphaImageFile.format, BmpAlphaImageFile)
# XXX register_save
Image.register_extension(BmpAlphaImageFile.format, ".bmp")
Vấn đề là ở đó đã là một plugin để xử lý" .bmp ", và tôi không bận tâm để tìm hiểu làm thế nào tôi có thể thêm phần mở rộng mới này vì vậy nó được sử dụng trước khi BmpImagePlugin được sử dụng (tôi cũng không biết nếu nó có thể làm điều đó trong PIL). Nói rằng, tôi thực sự đã sử dụng mã trực tiếp, như sau:
from BmpAlphaImagePlugin import BmpAlphaImageFile
x = BmpAlphaImageFile('gearscolor.bmp')
print x.mode
x.save('abc1.png')
Trường hợp gearscolor.bmp là bitmap mẫu có kênh alpha đầy đủ như được mô tả trước đó. Kết quả png được lưu với dữ liệu alpha. Nếu bạn kiểm tra mã của BmpImagePlugin.py
, bạn sẽ thấy rằng tôi đã sử dụng lại hầu hết mã của nó.
Tôi nghĩ rằng tệp bitmap 32 bit là định dạng không chuẩn mà PIL không hỗ trợ. Cố gắng để viết một hình ảnh RGBA để .bmp sản xuất lỗi 'không thể viết chế độ RGBA như BMP'. –