2012-01-04 16 views
8

Ho bisogno di creare un file BMP in bianco e nero con puro Python.Come posso creare un file BMP con Python puro?

Ho letto un articolo su wikipedia, BMP file format, ma non sono bravo a programmare a basso livello e voglio colmare questa lacuna nelle mie conoscenze.

Quindi la domanda è, come faccio a creare un file BMP in bianco e nero con una matrice di pixel? Ho bisogno di farlo con Python puro, non usando alcun modulo come PIL. È solo per la mia educazione

+1

Controlla il modulo ['struct'] (http://docs.python.org/library/struct.html). –

+1

Inoltre, controlla [questo thread del forum] (http://pseentertainmentcorp.com/smf/index.php?topic=2034.0). – Chewie

+0

Grazie, Chewie, è esattamente quello di cui ho bisogno –

risposta

3

è necessario utilizzare il modulo di Python struct per creare le intestazioni binario il file BMP avrà bisogno. Conserva i dati dell'immagine in un oggetto bytearray - bytearray è un tipo di dati python nativo poco conosciuto che può comportarsi come stringhe C: hanno byte mutabili che accettano numeri non firmati da 0-255 in ogni posizione, possono ancora essere stampati e usati come una stringa (come argomento per file.write, per esempio).

Ecco un piccolo programma che usa struct e altri strumenti per creare un'immagine e scriverlo come un file TGA, in puro Python, proprio come si vuole fare: http://www.python.org.br/wiki/ImagemTGA (non fa uso di bytearrays, ma python modulo matrice invece (che è anche interessante)

8

construct è una libreria puro Python per l'analisi e la costruzione di strutture binarie, protocolli e formati di file. ha supporto formati BMP out-of-the-box.

Questo potrebbe essere un approccio migliore rispetto alla creazione a mano con struct. Inoltre, avrai la possibilità di imparare una libreria veramente utile (che construct cer ramente è)

7

Questa è una risposta completa per le bitmap monocromatiche.

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

Ad esempio:

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 

Quindi, codifica questo come una serie di righe:

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

Render con:

bmp(smile, 8) 

noti che è il responsabilità del programmatore di assicurare che il nu mber di byte sono presenti in ogni riga fornita.

Il colore nero è specificato in \ xff \ xff \ xff e il colore bianco è specificato nel seguente \ x00 \ x00 \ x00, se si desidera cambiarli.

Problemi correlati