2012-01-04 76 views
8

Necesito crear un archivo BMP en blanco y negro con Python puro.¿Cómo creo un archivo BMP con Python puro?

He leído un artículo en wikipedia, BMP file format, pero no soy bueno en la programación de bajo nivel y quiero llenar este vacío en mi conocimiento.

Entonces, la pregunta es, ¿cómo creo un archivo BMP en blanco y negro que tiene una matriz de píxeles? Necesito hacer esto con Python puro, sin usar ningún módulo como PIL. Es solo por mi educación.

+1

Consulte el módulo ['struct'] (http://docs.python.org/library/struct.html). –

+1

Además, consulte [este hilo del foro] (http://pseentertainmentcorp.com/smf/index.php?topic=2034.0). – Chewie

+0

Gracias, Chewie, es exactamente lo que necesito –

Respuesta

3

Debe usar el módulo struct de Python para crear los encabezados binarios que necesitará el archivo BMP. Guarde los datos de la imagen en un objeto bytearray - bytearray es un tipo de datos de python nativo poco conocido que puede comportarse como cadenas de caracteres C: tiene bytes mutables que aceptan números sin firmar de 0-255 en cada posición, aún se pueden imprimir y usar como una cadena (como argumento para file.write, por ejemplo).

Aquí hay un pequeño programa que usa struct y otras herramientas para crear una imagen y escribirla como un archivo TGA, en Python puro, tal como lo quiere hacer: http://www.python.org.br/wiki/ImagemTGA (no utiliza bytearrays, sino python módulo de matriz en lugar (que también es interesante)

8

construct es una biblioteca de Python puro para el análisis y la construcción de estructuras binarias, protocolos y formatos de archivo. cuenta con formato BMP de la ayuda fuera de la caja.

Este podría ser un mejor enfoque que hacerlo a mano con struct. Además, tendrá la oportunidad de aprender una biblioteca realmente útil (que construct cer tainly es)

7

Esta es una respuesta completa para bitmaps monocromos.

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)])) 

Por ejemplo:

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 

Así, la codificación esto como una serie de filas:

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

hacerla con:

bmp(smile, 8) 

en cuenta que es la la responsabilidad del programador de garantizar que el número requerido mber de bytes están presentes en cada fila suministrada.

El color negro se especifica en \ xff \ xff \ xff y el color blanco se especifica en el siguiente \ x00 \ x00 \ x00, en caso de que desee cambiarlos.

Cuestiones relacionadas