Il formato BITMAP

Transcript

Il formato BITMAP
Il formato BITMAP
__________________________________________________________________________________________
Il formato BITMAP
Introduzione
Il Bitmap è il formato di visualizzazione delle immagini dei sistema
operativo Windows e, anche se è uno dei formati più vecchi, è ancora
molto utilizzato e soprattutto è molto portabile e riconosciuto da qualunque
piattaforma. In questo mini-tutorial dopo una prima trattazione generale
delle immagini in formato Bitmap, si approfondiranno la risoluzione a 8 bit
in scala di grigi e a 16 bit RGB.
Il formato BITMAP
Le immagini bitmap possono avere una profondità di 1, 4, 8, 16, 24 o 32
bit per pixell. Le bitmap con 1, 4 e 8 bit contengono una tavolozza (palette)
per la conversione dei (rispettivamente 2, 16 e 256) possibili indici
numerici nei rispettivi colori. Nelle immagini con profondità più alta il
colore non è indicizzato bensì codificato direttamente nelle sue componenti
cromatiche RGB; con 16 o 32 bit per pixel alcuni bit possono rimanere
inutilizzati.Ogni BMP contiene un Bitmap-file header, un Bitmap
information header, una palette di colori e un’array di byte che contiene i
pixel dell'immagine secondo la seguente struttura:
Header del file: BITMAPFILEHEADER
Blocco di informazioni: BITMAPINFO
 Header della Bitmap: BITMAPINFOHEADER
 Modello di colore (eventuale)
 Tavolozza (eventuale)
Mappa dei pixel
1
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
BITMAPFILEHEADER
Questo è l'header della bitmap che contiene informazioni sulla
grandezza in byte del file e l'offset dall'inizio del file del primo byte
nella mappa dei pixel.
BITMAPINFOHEADER
Qui sono indicate le dimensioni in pixel dell'immagine e il numero
di colori utilizzati. Le informazioni sono relative al dispositivo sul
quale la bitmap è stata creata. Sempre in questa struttura sono
indicate inoltre la risoluzione orizzontale e verticale del dispositivo
di output: questi valori, uniti a quelli della larghezza e dell'altezza
in pixel, determinano le dimensioni di stampa dell'immagine in
grandezza reale.
Modello di colore
Qui è possibile definire modelli di colore personalizzati. Nella
pratica queste strutture sono poco comuni.
Tavolozza (o palette)
Questa struttura è un array che fa corrispondere un colore ad ogni
indice che può essere assegnato ad un pixel. Nella tavolozza ogni
colore è rappresentato da una struttura di 4 byte (RGBQUAD), uno
ciascuno per i componenti rosso, verde e blu più un byte non
utilizzato. Nel caso di immagini con 16, 24 o 32 colori, questa
tabella di colori non è necessaria perché il colore dei pixel non è
indicizzato, bensì codificato direttamente nelle sue componenti.
Mappa dei pixel
Questa struttura di dati costituisce il corpo vero e proprio della
bitmap, dove ad ogni pixel si fa corrispondere un colore sotto forma
di indice nella tavolozza, oppure nelle sue componenti cromatiche.
2
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
È inoltre importante dire che le immagini bitmap sono memorizzate in
modalità bottom-up; cioè la prima riga della mappa dei pixel, in realtà è
l’ultima dell’immagine.
La seguente tabella contiene la descrizione dettagliata di un file bitmap.
Per ogni campo verranno dati l’offset all’interno del file, la dimensione in
byte e il contenuto.
offset
0
2
6
10
offset
14
18
22
BITMAPFILEHEADER (dimensione:14 bytes)
Dim(bytes)
nome
contenuto
2
bfType
la stringa ASCII "BM" (valore
decimale 19778, esadecimale 4D42)
4
bfSize
dimensione del file
4
bfReserved 0
4
bfOffBits offset del primo byte della mappa dei
pixel a partire dall'inizio del file
BITMAPINFOHEADER (dimensione:40 bytes)
Dim(bytes)
nome
contenuto
4
biSize
dimensione in byte del blocco
d'informazioni (valore decimale
40, esadecimale 28)
4
biWidth
larghezza dell'immagine in pixel
4
biHeight
altezza dell'immagine in pixel
(la mappa dei pixel incomincia
dalla riga di pixel più in basso e
finisce con quella più in alto)
26
28
2
2
biPlanes
biBitCount
30
4
biCompression
sempre 1
profondità
di
colore
dell'immagine in bit per pixel,
dev'essere uno dei seguenti
valori: 1, 4, 8, 16, 24 o 32. In
caso di 1, 4 o 8 bit per pixel i
colori sono indicizzati, nel caso
di 16 potrebbe essere necessario
introdurre opportune maschere
uno dei seguenti valori:
0 (BI_RGB)
La mappa dei pixel non è
compressa.
1 (BI_RLE8)
La mappa dei pixel è
compressa
con
3
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
34
4
38
4
42
4
46
4
l'algoritmo RLE per 8 bit
per pixel. Valido solo
per biBitCount = 8 e
biHeight > 0.
2 (BI_RLE4)
La mappa dei pixel è
compressa
con
l'algoritmo RLE per 4 bit
per pixel. Valido solo
per biBitCount = 4 e
biHeight > 0.
3 (BI_BITFIELDS)
La mappa dei pixel non è
compressa
ed
è
codificata
secondo
maschere
di
colore
personalizzate. Valido
solo per biBitCount = 16
o 32
biSizeImage
Indica la dimesione in byte del
buffer mappa dei pixel. Questo
valore può essere lasciato a zero
quando
biCompression
è
impostato a BI_RGB
biXPelsPerMeter risoluzione
orizzontale
del
dispositivo di output in pixel per
metro; 0 se la risoluzione non è
specificata
biYPelsPerMeter risoluzione
verticale
del
dispositivo di output in pixel per
metro; 0 se la risoluzione non è
specificata
biClrUsed
quando biBitCount = 1
0
quando biBitCount = 4 o 8
numero
di
corrispondenze
effettivamente utilizzate
nella
tavolozza
dei
colori; 0 indica il numero
massimo (16 o 256).
altrimenti
numero
di
corrispondenze
nella
tavolozza dei colori
(0 = nessuna tavolozza).
Per profondità maggiori
di 8 bit per pixel la
4
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
50
4
biClrImportant
54
N*4 bytes
Palette
(eventuale)
tavolozza
non
è
normalmente necessaria,
ma quando c'è può
essere usata dal sistema
o da alcuni programmi
per
ottimizzare
la
rappresentazione
dell'immagine
quando biBitCount = 1, 4 o 8
numero
di
colori
utilizzati nell'immagine;
0 indica tutti i colori
della tavolozza.
altrimenti
se la tavolozza esiste e
contiene tutti i colori
utilizzati nell'immagine
numero di colori
altrimenti
0
Definizione
delle
palette
(tavolozza). Per ogni elemento
nelle palette sono usati quattro
bytes per descrivere il valore
RGB del colore :
1 byte per la componente del blu
1 byte per la componente del
verde
1 byte per la componente del
rosso
1 byte di riempimento che è
sempre 0
Come detto in precedenza, in seguito a questi dati nel file vengono inseriti i
bytes che contengono la mappa dei pixel.
Si ritiene opportuno spiegare in maniera più esauriente il campo chiamato
biBitCount nel quale è indicato quanti bit corrispondono ad un singolo
pixel e quindi qual è il massimo numero di colori dell’immagine.
 Quando il numero di bit per pixel è uguale ad 1, l’immagine è
monocromatica e le palette contengono due elementi (8 bytes).
Ogni bit dell’immagine rappresenta un pixel e se questo bit è 0 è
5
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
visualizzato con i colori RGB del primo elemento delle palette, se 1
con il secondo.
 Quando il numero di bit per pixel è uguale ad 4, l’immagine ha un
massimo di 16 colori e le palette contengono 16 elementi (64
bytes). Ogni pixel dell’immagine è del colore RGB memorizzato
nelle palette nella posizione corrispondente ai suoi 4 bit. Ad
esempio se un byte dell’immagine è 2Fh esso rappresenta due
pixel: il primo del colore del secondo elemento delle palette e il
secondo del sedicesimo.
 Quando il numero di bit per pixel è uguale ad 8, l’immagine ha un
massimo di 256 colori e le palette contengono 256 elementi (1024
bytes). Ogni byte dell’immagine rappresenta un pixel.
 Quando il numero di bit per pixel è uguale ad 16, l’immagine ha un
massimo di 2^16 colori. Se il campo biCompression è settato a 0
(BI_RGB), il campo palette non contiene alcun elemento. In questo
caso abbiamo 5 bit per ogni componente di colore e il bit più
significativo inutilizzato. Significa che dei 16 bit che rappresentano
un pixel i 5 meno significativi sono la componente del blu, i 5
immediatamente successivi quella del verde e i degli ultimi 6 il più
significativo è inutilizzato e gli atri 5 sono la componente del rosso.
Se invece il campo biCompression è settato a 3 (BI_
BITFIELDS),
il
campo
palette
contiene
12
bytes
che
rappresentano 3 maschere rispettivamente per le componenti del
rosso, verde e blu (RGB). Se ad esempio dei 16 bit dell’immagine
ne sono utilizzati 5 per il rosso, 6 per il verde e 5 per il blu, la
maschera da inserire è: 0000F800h 000007E0h 0000001Fh. Questo
significa che dei 16 bit per pixel i 5 meno significativi sono la
componente del blu, i 6 immediatamente successivi quella del
verde e i 6 più significativi quella del rosso.
 Quando il numero di bit per pixel è uguale ad 24, l’immagine ha un
massimo di 2^24 colori e il campo palette non contiene alcun
6
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
elemento. Ogni pixel è rappresentato con tre bytes e ogni byte
rappresenta rispettivamente l’intensita di rosso, verde e blu.
 Quando il numero di bit per pixel è uguale ad 32, l’immagine ha un
massimo di 2^32 colori. Se il campo biCompression è settato a 0
(BI_RGB), il campo palette non contiene alcun elemento. In questo
caso abbiamo un byte per ogni componente di colore e il byte meno
significativo inutilizzato. Se invece il campo biCompression è
settato a 3 (BI_ BITFIELDS), il campo palette contiene 12 bytes
che rappresentano 3 maschere rispettivamente per le componenti
del rosso, verde e blu (RGB). È il caso analogo a quello spiegato
per le immagini a 16 bit per pixel solo che, ovviamente, ogni
maschera è composta da 4 bytes.
Intestazione per immagini ad 8 bit in scala di grigi
Nella figura sottostante si osserva parte dell’intestazione BITMAP di
un’immagine di dimensione 640x480 con risoluzione 8 bit in scala di grigi.
Offset
0
16
32
48
Bytes
42 4d 36 b4 04 00 00 00 00 00 36 04 00 00 28 00
00 00 80 02 00 00 e0 01 00 00 01 00 08 00 00 00
00 00 00 b0 04 00 00 00 00 00 00 00 00 00 00 01
00 00 00 00 00 00
Come spiegato nella tabella precedente, i primi 2 bytes sono la stringa
“BM” in hex 424d, la dimensione del file è 640x480 pixel ognuno dei quali
rappresentato da un byte (8 bit in scala di grigi) quindi abbiamo 307200
bytes per la mappa dei pixel + 54 bytes di intestazione + 1024 bytes per le
palette per un totale di 308278 bytes che in hex 04b436 che infatti è il
valore memorizzato nel campo bfSize. Notare che l’ordinamento dei byte è
little-endian (dal byte meno significativo a quello più significativo) quindi
nel file troviamo il numero 04b436 in modo 36b404. L’offset dell’inizio
della mappa dei pixel in hex è 0436 in quanto abbiamo, come detto prima,
54 bytes di intestazione + 1024 bytes per le palette per un totale di 1078
7
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
bytes che in hex 0436. Si notano poi, con gli opportuni offset, la
dimensione dell’immagine 0280x01e0 (640x480), il numero di piani (1), il
numero di bit per pixel (8), la dimensione della mappa dei pixel (04b000
hex  307200 dec) e il numero di colori significativi (100 hex  256
dec). Tra questa intestazione e la mappa di pixel devono essere inserite le
palette, che, come spiegato prima, stabiliscono la corrispondenza tra il
bytes che rappresenta il pixel e il corrispondente colore in RGB. Ogni
elemento delle palette è composto da 4 bytes: 1 per la componente del
rosso, uno per la componente del verde, uno per la componente del blu e
uno inutilizzato settato a zero. Dato che vogliamo ottenere immagini in
scala di grigi, per ogni elemento delle palette l’intensità dei tre colori sarà
la stessa in quanto la scala di grigi è sulla diagonale del cubo RGB. Ciò
significa che se un pixel, ad esempio, è rappresentato con il byte 1a, esso
farà riferimento all’elemento 1a delle palette che avrà memorizzati i
seguenti 4 bytes: 1a1a1a00 cioè intensità 1a per tutte e tre le componenti
più il quarto byte settato a zero. In seguito sono riportati i 1024 bytes per le
palette nel caso della risoluzione ad 8 bit in scala di grigio.
00 00 00 00 01 01 01 00 02 02 02 00 03 03 03 00 04 04 04 00 05 05 05 00 06 06 06 00 07
07 07 00 08 08 08 00 09 09 09 00 0a 0a 0a 00 0b 0b 0b 00 0c 0c 0c 00 0d 0d 0d 00 0e 0e
0e 00 0f 0f 0f 00 10 10 10 00 11 11 11 00 12 12 12 00 13 13 13 00 14 14 14 00 15 15 15
00 16 16 16 00 17 17 17 00 18 18 18 00 19 19 19 00 1a 1a 1a 00 1b 1b 1b 00 1c 1c 1c 00
1d 1d 1d 00 1e 1e 1e 00 1f 1f 1f 00 20 20 20 00 21 21 21 00 22 22 22 00 23 23 23 00 24
24 24 00 25 25 25 00 26 26 26 00 27 27 27 00 28 28 28 00 29 29 29 00 2a 2a 2a 00 2b 2b
2b 00 2c 2c 2c 00 2d 2d 2d 00 2e 2e 2e 00 2f 2f 2f 00 30 30 30 00 31 31 31 00 32 32 32
00 33 33 33 00 34 34 34 00 35 35 35 00 36 36 36 00 37 37 37 00 38 38 38 00 39 39 39 00
3a 3a 3a 00 3b 3b 3b 00 3c 3c 3c 00 3d 3d 3d 00 3e 3e 3e 00 3f 3f 3f 00 40 40 40 00 41 41
41 00 42 42 42 00 43 43 43 00 44 44 44 00 45 45 45 00 46 46 46 00 47 47 47 00 48 48 48
00 49 49 49 00 4a 4a 4a 00 4b 4b 4b 00 4c 4c 4c 00 4d 4d 4d 00 4e 4e 4e 00 4f 4f 4f 00 50
50 50 00 51 51 51 00 52 52 52 00 53 53 53 00 54 54 54 00 55 55 55 00 56 56 56 00 57 57
57 00 58 58 58 00 59 59 59 00 5a 5a 5a 00 5b 5b 5b 00 5c 5c 5c 00 5d 5d 5d 00 5e 5e 5e
00 5f 5f 5f 00 60 60 60 00 61 61 61 00 62 62 62 00 63 63 63 00 64 64 64 00 65 65 65 00
66 66 66 00 67 67 67 00 68 68 68 00 69 69 69 00 6a 6a 6a 00 6b 6b 6b 00 6c 6c 6c 00 6d
6d 6d 00 6e 6e 6e 00 6f 6f 6f 00 70 70 70 00 71 71 71 00 72 72 72 00 73 73 73 00 74 74
74 00 75 75 75 00 76 76 76 00 77 77 77 00 78 78 78 00 79 79 79 00 7a 7a 7a 00 7b 7b 7b
00 7c 7c 7c 00 7d 7d 7d 00 7e 7e 7e 00 7f 7f 7f 00 80 80 80 00 81 81 81 00 82 82 82 00
83 83 83 00 84 84 84 00 85 85 85 00 86 86 86 00 87 87 87 00 88 88 88 00 89 89 89 00 8a
8a 8a 00 8b 8b 8b 00 8c 8c 8c 00 8d 8d 8d 00 8e 8e 8e 00 8f 8f 8f 00 90 90 90 00 91 91
91 00 92 92 92 00 93 93 93 00 94 94 94 00 95 95 95 00 96 96 96 00 97 97 97 00 98 98 98
00 99 99 99 00 9a 9a 9a 00 9b 9b 9b 00 9c 9c 9c 00 9d 9d 9d 00 9e 9e 9e 00 9f 9f 9f 00 a0
a0 a0 00 a1 a1 a1 00 a2 a2 a2 00 a3 a3 a3 00 a4 a4 a4 00 a5 a5 a5 00 a6 a6 a6 00 a7 a7 a7
00 a8 a8 a8 00 a9 a9 a9 00 aa aa aa 00 ab ab ab 00 ac ac ac 00 ad ad ad 00 ae ae ae 00 af
af af 00 b0 b0 b0 00 b1 b1 b1 00 b2 b2 b2 00 b3 b3 b3 00 b4 b4 b4 00 b5 b5 b5 00 b6 b6
8
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
b6 00 b7 b7 b7 00 b8 b8 b8 00 b9 b9 b9 00 ba ba ba 00 bb bb bb 00 bc bc bc 00 bd bd bd
00 be be be 00 bf bf bf 00 c0 c0 c0 00 c1 c1 c1 00 c2 c2 c2 00 c3 c3 c3 00 c4 c4 c4 00 c5
c5 c5 00 c6 c6 c6 00 c7 c7 c7 00 c8 c8 c8 00 c9 c9 c9 00 ca ca ca 00 cb cb cb 00 cc cc cc
00 cd cd cd 00 ce ce ce 00 cf cf cf 00 d0 d0 d0 00 d1 d1 d1 00 d2 d2 d2 00 d3 d3 d3 00 d4
d4 d4 00 d5 d5 d5 00 d6 d6 d6 00 d7 d7 d7 00 d8 d8 d8 00 d9 d9 d9 00 da da da 00 db db
db 00 dc dc dc 00 dd dd dd 00 de de de 00 df df df 00 e0 e0 e0 00 e1 e1 e1 00 e2 e2 e2 00
e3 e3 e3 00 e4 e4 e4 00 e5 e5 e5 00 e6 e6 e6 00 e7 e7 e7 00 e8 e8 e8 00 e9 e9 e9 00 ea ea
ea 00 eb eb eb 00 ec ec ec 00 ed ed ed 00 ee ee ee 00 ef ef ef 00 f0 f0 f0 00 f1 f1 f1 00 f2
f2 f2 00 f3 f3 f3 00 f4 f4 f4 00 f5 f5 f5 00 f6 f6 f6 00 f7 f7 f7 00 f8 f8 f8 00 f9 f9 f9 00 fa
fa fa 00 fb fb fb 00 fc fc fc 00 fd fd fd 00 fe fe fe 00 ff ff ff 00
Il caso spiegato è quello di dimensione 640x480. Nel caso di altre
dimensioni dell’immagine si ragiona in maniera analoga e gran parte
dell’intestazione è la stessa tranne i campi che riguardano le dimensioni ai
quali, con accortezza, bisogneranno sostituire i valori opportuni.
Intestazione per immagini a 16 bit RGB
Nella figura sottostante si osserva l’intestazione BITMAP completa di
un’immagine di dimensione 640x480 con risoluzione 16 bit RGB.
Offset
0
16
32
48
64
Bytes
42 4d 42 60 09 00 00 00 00 00 42 00 00 00 28 00
00 00 80 02 00 00 e0 01 00 00 01 00 10 00 03 00
00 00 00 60 09 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 f8 00 00 e0 07 00 00 1f 00
00 00
Con un discorso analogo a quello effettuato per immagini in scala di grigi,
i primi 2 bytes sono la stringa “BM” in hex 424d, la dimensione del file è
640x480 pixel ognuno dei quali rappresentato da 2 bytes (16 bit RGB)
quindi abbiamo 614400 bytes per la mappa dei pixel + 54 bytes di
intestazione + 12 bytes per le maschere di colore per un totale di 614466
bytes che in hex 096042 che infatti è il valore memorizzato nel campo
bfSize sempre in modalità little-endian. L’offset dell’inizio della mappa dei
pixel in hex è 42 in quanto abbiamo, come detto prima, 54 bytes di
intestazione + 12 bytes per le palette per un totale di 66 bytes che in hex è
appunto 42. Si notano poi, con gli opportuni offset, la dimensione
dell’immagine 0280x01e0 (640x480), il numero di piani (1), il numero di
bit per pixel (10 hex  16 dec), il campo biCompression(3 cioè
9
____________________________________________________________
Il formato BITMAP
__________________________________________________________________________________________
BI_BITFIELDS cioè la mappa dei pixel non è compressa ed è codificata
secondo maschere di colore personalizzate), la dimensione della mappa dei
pixel (096000 hex  614400 dec) e gli ultimi 12 bytes che rappresentano
le maschere di colore. Il valore delle maschere è stato spiegato nel capitolo
precedente. Anche in questo caso, per formati diversi l’intestazione è
grossomodo la stessa tranne i campi dedicati alle dimensioni.
10
____________________________________________________________