2012-01-04 25 views
8

Tôi cần tạo tệp BMP màu đen và trắng bằng Python thuần túy.Làm cách nào để tạo tệp BMP bằng Python thuần túy?

Tôi đã đọc một bài viết trên wikipedia, BMP file format, nhưng tôi không giỏi lập trình ở mức độ thấp và muốn lấp đầy khoảng trống này trong kiến ​​thức của tôi.

Vì vậy, câu hỏi là, làm cách nào để tạo tệp BMP màu đen và trắng có ma trận pixel? Tôi cần phải làm điều này với Python thuần túy, không sử dụng bất kỳ mô-đun nào như PIL. Nó chỉ dành cho giáo dục của tôi.

+1

Xem mô-đun ['struct'] (http://docs.python.org/library/struct.html). –

+1

Ngoài ra, hãy kiểm tra [chuỗi diễn đàn này] (http://pseentertainmentcorp.com/smf/index.php?topic=2034.0). – Chewie

+0

Cảm ơn, Chewie, đó chính xác là những gì tôi cần –

Trả lời

3

Bạn phải sử dụng mô-đun struct của Python để tạo tiêu đề nhị phân mà tệp BMP sẽ cần. Giữ nguyên dữ liệu hình ảnh trong đối tượng bytearray - bytearray là một kiểu dữ liệu python ít được biết đến có thể hoạt động như chuỗi C: có byte có thể thay đổi chấp nhận số không dấu 0-255 ở mỗi vị trí, vẫn có thể được in và sử dụng dưới dạng chuỗi (ví dụ như một đối số cho file.write). Đây là một chương trình nhỏ sử dụng cấu trúc và các công cụ khác để tạo ra một hình ảnh và viết nó như một tệp TGA, bằng Python thuần túy, giống như bạn muốn làm: http://www.python.org.br/wiki/ImagemTGA (nó không sử dụng bytearrays, nhưng python mô-đun mảng thay vì (mà cũng là thú vị)

8

construct là một thư viện Python tinh khiết để phân tích và xây dựng các cấu trúc nhị phân, các giao thức và các định dạng tập tin. Nó có BMP định dạng hỗ trợ out-of-the-box.

này có thể là một cách tiếp cận tốt hơn so với việc chế tác thủ công nó với struct. Bên cạnh đó, bạn sẽ có cơ hội tìm hiểu một thư viện thực sự hữu ích (trong đó construct cer tainly is)

7

Đây là câu trả lời hoàn chỉnh cho bitmap đơn sắc.

import math, struct 

mult4 = lambda n: int(math.ceil(n/4))*4 
mult8 = lambda n: int(math.ceil(n/8))*8 
lh = lambda n: struct.pack("<h", n) 
li = lambda n: struct.pack("<i", n) 

def bmp(rows, w): 
    h, wB = len(rows), int(mult8(w)/8) 
    s, pad = li(mult4(wB)*h+0x20), [0]*(mult4(wB)-wB) 
    s = li(mult4(w)*h+0x20) 
    return (b"BM" + s + b"\x00\x00\x00\x00\x20\x00\x00\x00\x0C\x00\x00\x00" + 
      lh(w) + lh(h) + b"\x01\x00\x01\x00\xff\xff\xff\x00\x00\x00" + 
      b"".join([bytes(row+pad) for row in reversed(rows)])) 

Ví dụ:

FF XXXXXXXX 
81 X......X 
A5 X.X..X.X 
81 X......X 
A5 X.X..X.X 
BD X.XXXX.X 
81 X......X 
FF XXXXXXXX 

Vì vậy, mã hóa này là một loạt các hàng:

smile = [[0xFF], [0x81], [0xA5], [0x81], [0xA5], [0xBD], [0x81], [0xFF]] 

Render nó với:

bmp(smile, 8) 

Lưu ý rằng đó là trách nhiệm của lập trình viên để đảm bảo rằng các yêu cầu nu mber byte có mặt trong mỗi hàng được cung cấp.

Màu đen được chỉ định trong \ xff \ xff \ xff và màu trắng được chỉ định trong \ x00 \ x00 \ x00 sau, nếu bạn muốn thay đổi chúng.

Các vấn đề liên quan