close

BMP

Vai alla navigazione Vai alla ricerca
bitmap di Windows
Estensione .bmp[1] , [1] o [1].dib.rle
Tipo MIME immagine/bmp [2] [3]
Sviluppatore Microsoft [4] [5]
Tipo di formato grafica raster
 File multimediali su Wikimedia Commons

BMP ( dall'inglese.  B it m ap P icture ) è un formato di archiviazione bitmap sviluppato da Microsoft . I file in formato BMP possono avere le estensioni .bmp , .dib e .rle .

Un numero enorme di programmi funziona con il formato BMP, poiché il suo supporto è integrato nei sistemi operativi Windows e OS/2 . Inoltre, i dati in questo formato sono inclusi nei file di risorse RES binari e nei file PE .

Solo i raster a strato singolo possono essere archiviati in questo formato. Ogni pixel in diversi file può avere un diverso numero di bit (profondità del colore). Microsoft offre profondità di bit di 1, 2, 4, 8, 16, 24, 32, 48 e 64. A profondità di bit di 8 e inferiori, il colore è indicato da un indice della tabella dei colori (tavolozza) e per dimensioni maggiori quelli, da un valore diretto. In ogni caso, un colore può essere specificato solo nel modello colore RGB (sia quando specificato direttamente in un pixel che in una tabella colori), ma a 16 e 32 bit si può ottenere una scala di grigi con profondità fino a 16 e 32 bit, rispettivamente. La trasparenza parziale è implementata dal canale alfa di profondità di bit da 16 bit e superiori.

Nella maggior parte dei casi, i pixel vengono archiviati come un array bidimensionale relativamente semplice. Per le profondità di bit 4 e 8 è disponibile la codifica RLE , che può ridurne le dimensioni. Il formato BMP supporta anche l'incorporamento di dati JPEG e PNG . Ma quest'ultimo molto probabilmente non è destinato allo storage compatto, ma per aggirare i limiti dell'architettura GDI , che non prevede il lavoro diretto con immagini diverse dai formati BMP. Le ultime versioni del formato BMP hanno anche introdotto funzionalità di gestione del colore. In particolare, puoi specificare i punti finali, eseguire la correzione gamma e incorporare i profili colore ICC.

DIB e DDB

Quando si utilizza il formato DIB ( Device Independent Bitmap )  , un programmatore può accedere a tutti gli elementi delle strutture che descrivono un'immagine utilizzando un puntatore regolare. Ma questi dati non vengono utilizzati per il controllo diretto dello schermo, poiché vengono sempre archiviati nella memoria di sistema, non nella memoria video dedicata . Il formato dei pixel nella RAM può differire dal formato che deve essere memorizzato nella memoria video per indicare un punto dello stesso colore. Ad esempio, il formato DIB può utilizzare 24 bit per specificare un pixel e l'adattatore grafico in quel momento può funzionare in modalità HiColor con una profondità di colore di 16 bit. In questo caso, un punto rosso brillante in un formato indipendente dall'hardware sarà specificato da tre byte 0000FF 16 e nella memoria video - dalla parola F800 16 . Quando si copia un'immagine sullo schermo, il sistema impiegherà più tempo a convertire i codici colore dal formato a 24 bit al formato buffer video .

Il formato DDB ( Dependent Bitmap )  contiene sempre codici colore che corrispondono ai codici del buffer video , ma può essere archiviato sia nel sistema che nella memoria video. In entrambi i casi, contiene solo codici colore in un formato che garantirà il trasferimento dell'immagine dalla RAM alla memoria video mediante una semplice copia [6] .

Struttura interna

Image
Struttura del file BMP

Le informazioni ufficiali sul formato BMP possono essere trovate in MSDN o nella guida di Microsoft Windows SDK (potrebbe essere fornita in bundle con alcuni IDE). Il file WinGDI.h di Microsoft ha tutte le dichiarazioni C++ per questo formato. Questo articolo, tuttavia, non include dichiarazioni di tipo, poiché ciò può renderlo troppo ingombrante. Inoltre, alcuni sviluppatori potrebbero trovare scomodi gli annunci ufficiali e quindi la loro rilevanza è dubbia. Se hai bisogno dei nomi originali di costanti, strutture, tipi e dei loro campi, allora sono tutti nel testo di questo articolo.

La dimensione massima delle celle indivisibili (esclusi i campi delle strutture di bit): 32 bit e quindi il formato può essere classificato come 32 bit. Un'eccezione possono essere i pixel a 64 bit, ma i loro valori di canale possono anche essere elaborati con parole a 16 bit. L'ordine dei byte nelle celle a 16 e 32 bit è ovunque da basso a alto (little-endian). Gli interi sono scritti in codice diretto , con un segno di accesso aggiuntivo . Rispetto alle architetture hardware, l'ordine dei byte e il formato numerico corrispondono a x86 .

In questo articolo vengono utilizzati i nomi dei tipi WinAPI come nella documentazione Microsoft per specificare i tipi. Oltre a quelli specifici (descritti separatamente nel testo dell'articolo), si possono trovare quattro tipi numerici:

  • BYTE è un intero senza segno a 8 bit.
  • WORD è un intero senza segno a 16 bit.
  • DWORD è un intero senza segno a 32 bit.
  • LONG è un intero con segno a 32 bit.

Nel formato Windows Bitmap, le strutture sono intese come un blocco con celle consecutive di varie dimensioni fisse, che hanno nomi condizionali (esistono in molti linguaggi di programmazione) e non qualcosa di più complicato (ad esempio, un flusso di comandi di dimensioni arbitrarie).

Alcuni elementi di formato hanno una versione di Windows a partire dalla quale è supportato. Parliamo principalmente delle principali librerie WinAPI come gdi32.dll, shell32.dll, user32.dll e kernel32.dll. Altri componenti del sistema operativo (ad es. GDI+, .NET, DirectX) possono avere altre capacità più avanzate.

Struttura generale

I dati in formato BMP sono costituiti da tre blocchi principali di diverse dimensioni:

  1. L'intestazione dalla struttura BITMAPFILEHEADER e il blocco BITMAPINFO . Quest'ultimo contiene:
    1. campi di informazioni.
    2. Maschere di bit per l'estrazione dei valori del canale colore (opzionale).
    3. Cartella colori (opzionale).
  2. Profilo colore (opzionale).
  3. Dati pixel .

Quando sono archiviate in un file, tutte le intestazioni provengono dal primo byte. I dati dei pixel possono trovarsi in una posizione arbitraria nel file (è specificato nel campo OffBits della struttura BITMAPFILEHEADER), anche a distanza dalle intestazioni. Un profilo colore opzionale è apparso nella versione 5 e può anche essere posizionato liberamente, ma la sua posizione è specificata dall'inizio di BITMAPINFO (nel campo ProfileData).

Nella RAM (ad esempio, quando si interagisce con le funzioni GDI WinAPI), la struttura BITMAPFILEHEADER è esclusa dalle intestazioni. Allo stesso tempo, Microsoft consiglia di posizionare il profilo colore subito dopo le intestazioni in un unico blocco [7] . I dati dei pixel possono avere una posizione arbitraria nella memoria e il loro indirizzo è specificato nei parametri della procedura. In ogni caso, si raccomanda di mantenere tutti i blocchi in memoria ad indirizzi divisibili per quattro: ci sono celle a 32 bit nelle intestazioni, e tale requisito per i dati dei pixel è specificato nella documentazione [8] . Questo requisito vale solo per la RAM: se memorizzata in un file, non è necessario attenersi ad esso.

BITMAPFILEHEADER

BITMAPFILEHEADER è una struttura a 14 byte che si trova proprio all'inizio del file. Si noti che fin dall'inizio della struttura, l'allineamento delle celle viene perso. Se è importante per te, posiziona questa intestazione nella RAM a indirizzi pari che non sono multipli di quattro (quindi le celle a 32 bit cadranno in posizioni allineate).

Pos.
(esadecimale)
Dimensione
(byte)
Nome Tipo WinAPI Descrizione
00 2 bfType PAROLA Un segno per distinguere un formato da altri (formato firma). Può contenere il valore singolo 4D42 16 /424D 16 (little-endian/big-endian).
02 quattro bfSize DWORD Dimensione del file in byte.
06 2 bfRiservato1 PAROLA Riservato e deve essere zero.
08 2 bfRiservato2 PAROLA
0A quattro bfOffBits DWORD La posizione dei dati del pixel rispetto all'inizio di questa struttura (in byte).

La firma del formato quando si visualizza il contenuto di un file come testo in modalità binaria appare come una coppia di caratteri ASCII "BM".

BITMAPINFO

BITMAPINFO viene immediatamente dopo BITMAPFILEHEADER nel file. L'indirizzo di questo blocco in memoria viene anche passato direttamente ad alcune funzioni WinAPI (ad esempio, SetDIBitsToDevice o CreateDIBitmap). Inoltre, lo stesso blocco viene utilizzato nei formati di icone e cursori di Windows, ma questo punto non viene considerato in questo articolo (vedi descrizioni separate di questi formati). Questa struttura è di base e descrittiva nel formato BMP, quindi quando il nome di un campo viene semplicemente menzionato, allora è un campo in questa struttura.

Il blocco BITMAPINFO è composto da tre parti:

  1. Struttura con campi informativi.
  2. Maschere di bit per l'estrazione dei valori del canale colore (non sempre presenti).
  3. Tavola colori (non sempre presente).

Informazioni sulle maschere di bit e sulla tabella dei colori, vedere di seguito in sezioni separate. Di seguito, seguirà la descrizione della struttura con i campi informativi.

Al momento della stesura di questo articolo, la struttura con i campi di informazioni aveva quattro versioni [9] : CORE, 3, 4 e 5 (le designazioni delle versioni sono condizionali all'interno di questo articolo per brevità). Per ogni versione, Microsoft ha dichiarato quattro strutture separate con nomi di campo diversi. In questo articolo, quando si menziona un campo che è presente in più strutture, alla fine del nome viene presa la parte comune a tutte le strutture (ad esempio, BitCount invece di bcBitCount, biBitCount, bV4BitCount o bV5BitCount). La versione della struttura può essere determinata dalla prima cella a 32 bit (tipo WinAPI DWORD), che contiene la sua dimensione in byte (un intero senza segno). La versione CORE si differenzia da tutte per la compattezza e l'utilizzo di campi esclusivamente a 16 bit senza segno. I restanti tre contengono celle identiche, a cui ne sono state aggiunte di nuove in ogni nuova versione.

Di seguito una tabella riepilogativa delle strutture informative:

Versione Dimensione
(byte)
Nome struttura Versione Windows 9x / NT [10] Windows CE / versione Mobile [11] Appunti
NUCLEO 12 BITMAPCOREHEADER 95/NT 3.1 e precedenti CE 2.0/Mobile 5.0 e versioni successive Contiene solo la larghezza, l'altezza e la profondità di bit del raster.
3 40 BITMAPINFHEADER 95/NT 3.1 e precedenti CE 1.0/Mobile 5.0 e versioni successive Contiene la larghezza, l'altezza e la profondità di bit di un raster, nonché le informazioni su formato pixel, tabella dei colori e risoluzione.
quattro 108 BITMAPV4HEADER 95/NT 4.0 e precedenti non supportato Maschere di canale selezionate separatamente, informazioni aggiunte sullo spazio colore e sulla gamma.
5 124 BITMAPV5HEADER 98/2000 e precedenti non supportato Aggiunta strategia di visualizzazione delle preferenze e supporto per i profili ICC.

A causa dell'identità dei campi nelle versioni 3, 4 e 5, può sembrare che il campo Dimensione possa controllare il numero di campi, rimuovendo quelli non utilizzati. In realtà, questo non è corretto, poiché qui la dimensione gioca il ruolo della versione (nella versione CORE, sebbene anche i campi siano identici, ma di dimensione e tipo diversi). Nessuno garantisce che non otterrai intestazioni più piccole o più grandi con un diverso insieme di campi. Tuttavia, Adobe Photoshop può salvare strutture di campi di informazioni a 52 e 56 byte durante il salvataggio di file BMP. In effetti, questa è una 4a versione troncata, che contiene solo maschere di bit dei canali (56 byte - versione con canale alfa).

Campi di informazioni a 16 bit (versione CORE)

Si noti che qui i campi di larghezza e altezza contengono interi senza segno, mentre le strutture a 32 bit memorizzano valori con segno.

Posizione
nel file
(esadecimale)
Posizione
nella struttura
(esadecimale)
Dimensione
(byte)
Nome Tipo WinAPI Descrizione
0E 00 quattro bcSize DWORD La dimensione di questa struttura in byte, indicando anche la versione della struttura (dovrebbe essere 12 qui).
12 04 2 bc Larghezza PAROLA Larghezza (bcWidth) e altezza (bcHeight) del raster in pixel. Specificato come intero senza segno. Il valore 0 non è documentato.
quattordici 06 2 bcAltezza PAROLA
16 08 2 bcPlanes PAROLA L'unico valore valido in BMP è 1. Questo campo viene utilizzato nelle icone e nei cursori di Windows.
diciotto 0A 2 bcBitCount PAROLA Il numero di bit per pixel (vedere l'elenco di quelli supportati in una sezione separata di seguito).

Campi di informazioni a 32 bit (versioni 3, 4 e 5)

La tabella seguente fornisce una panoramica dei campi. Puoi trovare informazioni dettagliate nelle sezioni seguenti.

Posizione
nel file
(esadecimale)
Posizione
nella struttura
(esadecimale)
Dimensione
(byte)
Nome
(versioni 3/4/5)
Tipo WinAPI Descrizione
0E 00 quattro biTaglia
bV4Taglia
bV5Taglia
DWORD La dimensione di questa struttura in byte, indicando anche la versione della struttura (vedi tabella delle versioni sopra).
12 04 quattro biLarghezza
bV4Larghezza
bV5Larghezza
LUNGO La larghezza del raster in pixel. Specificato come numero intero con segno. Zero e negativo non sono documentati.
16 08 quattro biAltezza
bV4Altezza
bV5Altezza
LUNGO Un numero intero con segno che contiene due parametri: l'altezza del raster in pixel (il valore assoluto del numero) e l'ordine in cui le stringhe vengono visualizzate negli array bidimensionali (il segno del numero). Il valore nullo non è documentato.
1A 0C 2 biPlanes
bV4Planes
bV5Planes
PAROLA L'unico valore valido in BMP è 1. Questo campo viene utilizzato nelle icone e nei cursori di Windows.
1C 0E 2 biBitCount
bV4BitCount
bV5BitCount
PAROLA Il numero di bit per pixel (consultare l'elenco di quelli supportati in una sezione separata di seguito ).
1E dieci quattro biCompressione
bV4V4Compressione [12]
bV5Compressione
DWORD Specifica come vengono archiviati i pixel (vedere la sezione seguente ).
22 quattordici quattro biSizeImage
bV4SizeImage
bV5SizeImage
DWORD La dimensione dei dati del pixel in byte. Può essere impostato su zero se la memoria è un array bidimensionale.
26 diciotto quattro biXPelsPerMeter
bV4XPelsPerMeter
bV5XPelsPerMeter
LUNGO Il numero di pixel per metro in orizzontale e in verticale (consultare la sezione " Risoluzione dell'immagine " di questo articolo).
2A 1C quattro biYPelsPerMeter
bV4YPelsPerMeter
bV5YPelsPerMeter
LUNGO
2E venti quattro biClrUsed
bV4ClrUsed
bV5ClrUsed
DWORD La dimensione della tabella dei colori nelle celle.
32 24 quattro biClrImportante
bV4ClrImportante
bV5ClrImportante
DWORD Il numero di celle dall'inizio della tabella dei colori all'ultima utilizzata (incluso se stesso).
Aggiunto nella versione 4
Posizione
nel file
(esadecimale)
Posizione
nella struttura
(esadecimale)
Dimensione
(byte)
Nome
(versioni 4/5)
Tipo WinAPI Descrizione
36 28 quattro bV4RedMask
bV5RedMask
DWORD Maschere di bit per l'estrazione dei valori dei canali : rosso, verde, blu intensità e valore del canale alfa.
3A 2C quattro bV4GreenMask
bV5GreenMask
DWORD
3E trenta quattro bV4BlueMask
bV5BlueMask
DWORD
42 34 quattro bV4AlphaMask
bV5AlphaMask
DWORD
46 38 quattro bV4CSType
bV5CSType
DWORD Tipo di spazio colore .
4A 3C 36 bV4
Endpoint bV5 Endpoint
CIEXYZTRIPLE Il valore di questi quattro campi viene preso in considerazione solo se il campo CSType contiene 0 (LCS_CALIBRATED_RGB). Quindi in questi campi vengono specificati i punti finali e i valori gamma per le tre componenti del colore.
6E 60 quattro bV4GammaRed
bV5GammaRed
DWORD [13]
72 64 quattro bV4GammaGreen
bV5GammaGreen
DWORD [13]
76 68 quattro bV4GammaBlue
bV5GammaBlue
DWORD [13]
Aggiunto nella versione 5
Posizione
nel file
(esadecimale)
Posizione
nella struttura
(esadecimale)
Dimensione
(byte)
Nome Tipo WinAPI Descrizione
7A 6C quattro bV5 Intento DWORD Preferenze di rendering raster .
7E 70 quattro bV5Dati profilo DWORD L' offset di byte del profilo colore dall'inizio di BITMAPINFO (vedere anche la sezione Profilo colore più avanti in questo articolo).
82 74 quattro bV5 Dimensione profilo DWORD Se un profilo colore è incluso direttamente nel BMP, qui viene indicata la sua dimensione in byte.
86 78 quattro bV5 Riservato DWORD Riservato e deve essere impostato su zero.

Bitness dell'immagine (campo BitCount)

Il campo BitCount contiene il numero di bit per pixel. Se viene indicato un valore diverso da zero, allora questa è la profondità di bit reale. Il contenuto zero del campo BitCount è indicato se i pixel sono archiviati in formato JPEG o PNG. Quindi la profondità di bit effettiva sarà determinata da questi formati. I bit del formato BMP puro sono presentati nella tabella seguente:

Morso Byte BITMAPINFO RLE Maschere di canale Supporto software
NUCLEO 3, 4, 5 Windows 9x e NT Windows CE e Mobile GDI+ e .NET
uno Non Non
2 ¼ Non Non Non Non
quattro ½ Non
otto uno Non
16 2 Non Non
24 3 Non Non
32 quattro Non Non
48 6 Non Non Non Non Non
64 otto Non Non Non Non Non

Note alla tabella:
1. La colonna "BITMAPINFO" mostra il supporto della profondità di bit solo da Microsoft.
2. Windows CE 1.0 e 1.01 supportano solo profondità di bit 1 e 2 [14] .
3. I canali colore GDI+ versione 1.0 a 16 bit possono essere solo letti, convertendoli immediatamente in 8 bit [15] .

A profondità di bit di 8 e inferiori, il colore di un pixel è indicato da un indice nella tabella dei colori, in bit più alti: da un valore diretto nel modello di colore RGB . Opzionalmente è possibile aggiungere un canale alfa a 16 e 32 bit, a 64 bit è permanentemente presente.

La tabella mostra solo il bit che Microsoft ha documentato. Il formato stesso non contiene alcuna restrizione fondamentale sull'uso di qualsiasi bit non menzionato qui.

I file BMP a 1 bit con nero puro (bit off) e bianco (bit on) sono chiamati monocromatici. Tali file vengono solitamente utilizzati come maschere per altre bitmap. Forse ti sei imbattuto costantemente in tali raster a 1 bit. In effetti, il formato Bitmap di Windows non impone alcuna restrizione su quali colori verranno utilizzati per ciascuno dei valori di bit.

Potresti anche imbatterti nei seguenti nomi di bit: CGA per due bit, EGA per quattro, HiColor (HighColor) per 16 bit, TrueColor per 24 e 32 bit con traslucenza, DeepColor per bit alti e possibilmente altri. Questi nomi risalgono allo sviluppo delle visualizzazioni bitmap a colori e si riferiscono maggiormente alla loro profondità di colore . Al momento della stesura di questo articolo (2014), tali nomi non sono stati utilizzati per molto tempo a causa della forte prevalenza di dispositivi a 24 bit (invece, viene semplicemente indicata la profondità del colore in bit o il loro numero). E i file BMP con bit inferiore vengono salvati in misura maggiore non per la visualizzazione su dispositivi CGA o EGA, ma per compattezza rispetto ai formati a 24 bit e 32 bit se viene utilizzato un numero ridotto di colori.

Campo di compressione

Per ciascun gruppo di bit vengono utilizzati valori di compressione limitati separati, ma nell'aggregato i loro valori sono univoci. Microsoft ha documentato i seguenti valori (la tabella elenca i nomi delle costanti di questa società):

Significato Nome costante Applicabile
a BitCount
Memoria dei pixel Segno di altezza Versione Windows
9x/NT CE
0 BI_RGB qualsiasi tranne zero matrice bidimensionale +/- 95/NT3.1 CE 1.0
uno BI_RLE8 otto Codifica RLE + 95/NT3.1 (non sub.)
2 BI_RLE4 quattro Codifica RLE + 95/NT3.1 (non sub.)
3 BI_BITFIELDS 16 e 32 Array 2D con maschere di canali di colore +/- 95/NT3.1 CE 2.0
quattro BI_JPEG 0 nel file jpeg incorporato ?/- [16] 98/2000 (non sub.)
5 BI_PNG 0 nel file PNG incorporato ?/- [16] 98/2000 (non sub.)
6 CAMPI BI_ALFABIT 16 e 32 Array 2D con maschere di colore e canale alfa +/- (non sub.) .NET 4.0

Cartella colori

La tavola dei colori fa parte del blocco BITMAPINFO e può essere utilizzata in due modi:

  1. È necessariamente presente a profondità di bit di 8 e inferiori, in cui il colore del pixel è specificato dall'indice della cella da esso.
  2. A profondità di bit pari o superiori a 8, in cui il colore è indicato da un valore immediato, la tabella è presente se viene utilizzata un'intestazione di versione non CORE, in cui il campo ClrUsed contiene un valore diverso da zero. Qui viene già utilizzato per ottimizzare i colori quando si lavora con i dispositivi utilizzando le tavolozze (la documentazione non dice esattamente come viene eseguita l'ottimizzazione).

La posizione della tavola dei colori è specificata dall'inizio del blocco BITMAPINFO. Per impostazione predefinita, viene immediatamente dopo la struttura delle informazioni (la sua dimensione senza segno in byte può essere letta dal primo campo a 32 bit). Ma tra la struttura con campi e la tabella dei colori, è possibile utilizzare maschere di bit a quattro byte per estrarre i canali del colore (vale solo per 16 e 32 bit). Sono presenti solo se viene utilizzata la struttura delle informazioni versione 3 (Size = 40) e il campo Compressione contiene 3 (BI_BITFIELDS) o 6 (BI_ALPHABITFIELDS). Quindi 12 byte (se è specificato BI_BITFIELDS) o 16 byte (se è specificato BI_ALPHABITFIELDS) [17] devono essere aggiunti alla dimensione dei campi di informazioni . Risulta 6 opzioni per la posizione del tavolo:

Versione
intestazione
Posizione (esadecimale) Appunti
In archivio In BITMAPINFO
NUCLEO 1A 0C le maschere di canale non sono supportate
3 36 28 La compressione non contiene 3 o 6
42 34 Compressione = 3 (BI_BITFIELDS)
46 38 Compressione = 6 (BI_ALPHABITFIELDS)
quattro 7A 6C le maschere di canale sono incorporate
nei campi delle informazioni
5 8A 7B

Il numero di celle nella tabella è determinato dai campi BitCount e ClrUsed. Con profondità di bit pari o inferiori a 8, il numero massimo di celle nella tabella viene preso come 2 bit : 2 in un raster a un bit, 4 in uno a due bit, 16 in uno a 4 bit e 256 in un 8 -un po'. Nel bit specificato, la tabella contiene sempre questo numero massimo di celle se viene utilizzata l'intestazione della versione CORE (Size = 12) o se il campo ClrUsed contiene 0 in altre versioni.In tutti gli altri casi, indipendentemente dal bit, la tabella contiene tante celle quante sono specificate nel campo ClrUsed [18] .

La tabella stessa è un array unidimensionale che può contenere tre tipi di celle:

  1. Struttura RGBQUAD a 32 bit . Viene utilizzato se in BITMAPINFO viene utilizzata la struttura delle informazioni della versione 3, 4 o 5. Nella stessa struttura RGBQUAD, il colore nel modello RGB è indicato in quattro celle di byte (tutte hanno il tipo BYTE WinAPI): rgbBlue (blu) , rgbGreen (verde), rgbRed (rosso ) e rgbReserved (riservato e deve essere impostato su zero).
  2. Struttura RGBTRIPLE a 24 bit . Si applica se BITMAPINFO inizia con una struttura BITMAPCOREHEADER. RGBTRIPLE è costituito da tre celle di byte (WinAPI tipo BYTE) che specificano un colore nel modello RGB : rgbtBlue (blu), rgbtGreen (verde) e rgbtRed (rosso).
  3. Indici di colore a 16 bit (interi senza segno) nella tavolozza logica corrente del contesto del dispositivo ( oggetti di sistema GDI di Windows ). Questa visualizzazione è disponibile solo mentre l'applicazione è in esecuzione. Il formato BMP non supporta un'indicazione esplicita dell'utilizzo di tale tabella, e quindi l'applicazione stessa lo notifica alle funzioni WinAPI in parametri speciali (di solito la costante DIB_PAL_COLORS).

Non tutte le celle possono essere utilizzate nell'intera tabella e il campo ClrImportant contiene il numero di celle dall'inizio della tabella all'ultima utilizzata (incluso se stesso). Un valore 0 nel campo ClrImportant indica che viene utilizzata l'intera tabella. È meglio posizionare le celle coinvolte all'inizio della tabella e si consiglia di ordinarle in ordine decrescente di importanza (nel caso in cui sia necessario ridurne il numero).

Maschere per estrarre i valori del canale colore

Se l'immagine è a 16 o 32 bit, è possibile specificare maschere a 32 bit per estrarre i canali di colore. Questo perché 16 non è un multiplo di 3 e quindi i bit possono essere allocati in modi diversi. Per comodità, le immagini a 32 bit utilizzano canali a 8 bit e pertanto il loro supporto potrebbe sembrare ridondante. Infatti, qui la maschera permette di abilitare/disabilitare il canale alfa o impostare l'ordine dei componenti che fa per voi, e non solo di regolarne la risoluzione. Quando si applicano le maschere, la cella del pixel viene letta nella sua interezza come la parola macchina corrispondente in little-endian.

La presenza di maschere di bit dipende dalla versione dei campi informativi della struttura BITMAPINFO e dal campo Compressione in essa contenuta. Per la versione CORE, non è possibile specificare maschere arbitrarie, poiché non esiste un campo Compressione e campi maschera separati. In altre versioni, le maschere colore sono abilitate se Compressione contiene 3 (BI_BITFIELDS). La maschera del canale alfa è sempre utilizzata nelle versioni 4 e 5. Poiché Windows CE non supporta queste due versioni, in cui è presente un campo speciale, per la terza versione è stato introdotto il valore 6 (BI_ALPHABITFIELDS) del campo Compressione, che aggiunge sia le maschere di colore che un canale alfa della maschera (supportato da Windows CE .NET 4.0).

La posizione delle maschere di bit è fissa indipendentemente dalla versione dell'intestazione: 36 h nell'intero file o 28 h dall'inizio del blocco BITMAPINFO. Nelle versioni 4 e 5, i campi progettati appositamente per loro si trovano in questo luogo. Nella versione 3, le maschere di bit dovrebbero trovarsi subito dopo i campi di informazioni e quindi nelle versioni precedenti esse ricadono esattamente nelle posizioni dei campi corrispondenti. Si noti che nella terza versione, se sono presenti delle maschere, la tabella dei colori viene spostata in avanti di 12 o 16 byte, posizionata immediatamente dopo di esse. Le maschere colorate a 4 byte sono nell'ordine rosso, verde, blu. La maschera del canale alfa è già dietro di loro.

La documentazione di Microsoft si applica solo a un requisito obbligatorio per le maschere di bit: ciascuna maschera deve essere contigua. Sul caso dell'intersezione delle mascherine, vi si dice che è auspicabile non farlo [19] . Microsoft afferma inoltre che non è necessario utilizzare tutti i bit di un pixel [20] . Non ci sono requisiti per il contenuto dei bit inutilizzati.

Si noti che nessuno garantisce che possano essere utilizzate maschere più larghe di 8 bit. E non viene detto nulla sul caso in cui qualsiasi canale avrà una maschera nulla (ad esempio, quando non viene effettivamente utilizzato). Qui è possibile una situazione in cui tutti i componenti avranno zero maschere e rimarrà un canale alfa (che, in questo caso, può occupare tutti i bit). La maschera zero di un canale colore può essere interpretata in due modi: il suo valore viene preso come zero, oppure i pixel di questo canale non vengono influenzati durante il disegno. Se prendiamo la prima interpretazione con un singolo canale alfa, allora il canale alfa imposterà essenzialmente il grado di annerimento del pixel. Oltre alle vaghe opzioni, ce n'è anche una interessante. Poiché le intersezioni non sono vietate, è possibile impostare tutti i canali in una posizione e quindi ottenere una scala di grigi .

Alcuni software hanno un set limitato di maschere di bit supportate. La tabella seguente elenca le opzioni disponibili in questi ambienti limitati:

Bitness * Valori maschera (esadecimale) Supporto software
Rosso Verde Blu Alfa Inutilizzato Windows 9x [21] GDI+ [22] e .NET [23]
16 (un) 7C00 03E0 001F 0000 8000
7C00 03E0 001F 8000 0000 Non
F800 07E0 001F 0000 0000
(b) FFFF FFFF FFFF 0000 0000 Non
32 (un) 00FF:0000 0000:FF00 0000:00FF 0000:0000 FF00:0000
00FF:0000 0000:FF00 0000:00FF FF00:0000 0000:0000 Non

Note sulla tabella:
(a) Questi set vengono utilizzati per impostazione predefinita a 16 e 32 bit se le maschere di estrazione del colore non sono specificate.
(b) Questo set di maschere implementa intrinsecamente una scala di grigi a 16 bit.

Dati pixel

Nel file, la posizione dei dati dei pixel si trova nel campo OffBits della struttura BITMAPFILEHEADER. In fase di esecuzione, l'applicazione memorizza l'indirizzo dei dati del pixel dove è conveniente. La documentazione Microsoft menziona anche le cosiddette bitmap imballate , che sono indicate da un unico indirizzo del blocco BITMAPINFO. Per tali bitmap, i dati dei pixel seguono immediatamente l'intestazione (includendo, oltre ai campi informativi, le maschere di bit e una tabella dei colori) [24] .

La dimensione dei dati in pixel in byte è memorizzata nel campo SizeImage della struttura BITMAPINFO. È la dimensione “grezza” di quel blocco continuo che contiene i dati per la formazione dei pixel (indipendentemente dal formato), e non uno spacchettato, che viene scritto lì. Per impostazione predefinita, questo campo deve contenere il valore corrente, poiché può essere utilizzato per scoprire esattamente quanti byte devono essere letti dal file per ottenere pixel. Tuttavia, è consentito mantenere questo campo zero quando si archiviano pixel come array bidimensionali (quando il campo Compressione contiene il valore 0 (BI_RGB), 3 (BI_BITFIELDS) o 6 (BI_ALPHABITFIELDS) [25] ). Quindi la dimensione dei pixel, se necessario, può essere calcolata in modo relativamente rapido in base alla profondità di bit, alla larghezza e all'altezza del raster.

Esistono tre modi per archiviare i pixel nel formato Bitmap di Windows (vedi anche la sezione Campo di compressione di questo articolo):

  1. matrice 2D .
  2. Codifica RLE (solo per 4 e 8 bit).
  3. Nei formati JPEG o PNG .

Le sottosezioni seguenti descrivono ciascuno di essi separatamente.

Specificare il colore e il valore del canale alfa

Per specificare un colore quando viene memorizzato in formato BMP, indipendentemente da come viene specificato, vengono utilizzati solo numeri interi senza segno. Il colore del pixel stesso può essere impostato in due modi:

  1. Un indice nella tabella dei colori (con profondità di bit di 8 e inferiori).
  2. Un valore immediato nel modello di colore RGB (con bit superiori a 8).

Il secondo è utile quando l'insieme dei colori è abbastanza grande o imprevedibile (ad esempio, durante l'elaborazione delle immagini). Il primo metodo fornisce sia un layout compatto con un piccolo set di colori, sia una certa comodità nella gestione dei colori utilizzati (basta modificare il valore del colore nella tavolozza). La tabella dei colori stessa è specificata come indici senza segno a 16 bit nella tavolozza di sistema (vedere la sezione " Tabella dei colori " in questo articolo) o in RGB come in un pixel, ma esclusivamente da valori di canale a 8 bit.

L'indice nella tabella dei colori è il numero di cella in essa contenuto dall'inizio della tabella (viene utilizzata la numerazione continua a partire da zero). Per ciascuna profondità di bit, l'indice massimo è fondamentalmente limitato dal valore 2 bit depth - 1. In realtà, è limitato anche dal numero di elementi nella tabella (dettagli nella sezione " Tabella dei colori " di questo articolo). Microsoft non ha documentato il comportamento quando viene specificato un indice esterno alla tabella, ma in questo caso GDI diventa nero.

A profondità di bit superiori a 8, il colore di un pixel è indicato direttamente nel modello di colore RGB: il livello di rosso, verde e blu è indicato separatamente. Il valore zero di uno qualsiasi dei canali significa la completa assenza della tonalità corrispondente e il massimo: la sua completa presenza. La risoluzione dei valori del canale è variabile e ha la sua in ogni profondità di bit (per valori specifici, vedere la sezione sulla memorizzazione dei pixel in una matrice bidimensionale di questo articolo). Allo stesso tempo, a profondità di bit di 16 e 32, è possibile impostare non solo una risoluzione arbitraria, ma anche individuale per ciascun canale (ad esempio, 5 bit per rosso e blu, ma 6 bit per verde). Nonostante il gran numero di opzioni per impostare la risoluzione dei valori, la documentazione Microsoft non dice come modificare la risoluzione di un valore. Per questo motivo, diversi produttori di software possono ottenere risultati diversi quando si modifica la profondità di bit.

Quando si imposta direttamente il colore di un pixel, oltre ai valori RGB, il formato Windows Bitmap facoltativamente consente anche di impostare i valori del canale alfa . In termini di bit e codifica dei valori, è identico ai canali di colore: ha un bit arbitrario e vengono utilizzati interi senza segno. Per quanto riguarda la corrispondenza dei valori, lo zero corrisponde alla piena trasparenza e il numero massimo disponibile corrisponde al pieno riempimento.

Matrice bidimensionale

I pixel di qualsiasi bit possono essere archiviati in una matrice bidimensionale. Con questo metodo di archiviazione, il campo Compressione contiene il valore 0 (BI_RGB), 3 (BI_BITFIELDS) o 6 (BI_ALPHABITFIELDS). Se viene utilizzata l'intestazione della versione CORE, i pixel vengono comunque archiviati solo come array bidimensionale.

In questo layout, i pixel raster sono scritti come strisce orizzontali a pixel singolo, che Microsoft chiama spesso " scansioni " nella sua documentazione (in russo, la parola più vicina è righe ). In memoria, queste righe sono scritte in ordine, ma con un'altezza positiva: partendo da quella inferiore ( bitmap inglese  bottom-up ), e con un'altezza negativa: dall'alto ( bitmap inglese  top-down ). All'interno di ogni riga orizzontale, i pixel sono scritti rigorosamente solo da sinistra a destra. I pixel inferiori a 8 bit vengono inseriti nei byte, riempiendo i bit dall'alto al basso, risultando nei valori numerici esadecimali/binari dei pixel più simili all'immagine di output. Se la profondità di bit è 16 o 32, l'elaborazione viene eseguita da intere parole macchina della stessa dimensione con l'ordine dei bit da basso a alto (Little Endian). Le righe, indipendentemente dalle dimensioni della cella, devono essere riempite con zeri fino a un multiplo di quattro byte di dimensione [8] . Per questo motivo, con una larghezza dell'immagine non multipla, alla fine delle righe possono apparire bit o interi byte inutilizzati. Ma grazie alla molteplicità garantita della dimensione della riga, l'elaborazione può essere eseguita con parole macchina a 8, 16 o 32 bit, a scelta. E Microsoft ha ancora la seguente tendenza in profondità di bit maggiori di 8: il componente blu (blu) è posizionato nei bit inferiori / primi byte, verde (verde) in quello successivo e rosso (rosso) è più vecchio / più lontano e se c'è un canale alfa, quindi è nei bit più significativi/ultimi byte.

Il diagramma seguente mostra la disposizione dei pixel in bit inferiori a 8 :

bit 7 6 5 quattro 3 2 uno 0
1 bit 0 uno 2 3 quattro 5 6 7
2 bit 0 uno 2 3
4 bit 0 uno

A 16 e 32 bit, i pixel vengono elaborati da parole macchina della stessa dimensione (assumendo l'ordine dei byte little-endian), che applicano le maschere di bit del canale . Se non vengono fornite singole maschere di bit, la struttura sarà la seguente. A 16 bit, a ciascun canale vengono assegnati 5 bit. Il blu è nei bit meno significativi (maschera 001F 16 ), il verde è in posizione 5 (maschera 03E0 16 ), il rosso: a partire dal 10° bit (maschera 7C00 16 ), e il restante bit più significativo 15 non viene utilizzato. Se vengono utilizzati 32 bit, per impostazione predefinita a ciascun canale viene assegnato un byte (8 bit). I componenti sono disposti in modo simile: blu nei bit bassi (maschera 0000:00FF 16 ), verde a partire dal bit 8 (maschera 0000:FF00 16 ), rosso a partire dal bit 16 (maschera 00FF:0000 16 ), e il byte alto è non utilizzato (viene usato come canale alfa solo se lo mostri direttamente) [26] . Dal momento che dovrebbe essere letto nell'ordine dei byte little-endian, se leggi i valori dalla memoria byte per byte, saranno nello stesso ordine (il blu verrà prima).

Con una profondità di bit di 24 , ogni canale ha un byte e con una profondità di bit di 48 e 64 : una parola macchina a 16 bit. In tutti e tre i casi, in memoria, le componenti colore vanno nell'ordine: blu, verde, rosso. Nei BMP a 64 bit, i colori sono inoltre seguiti da un canale alfa a 16 bit. Se si desidera elaborare un pixel a 64 bit con una singola parola macchina, il blu little-endian sarà nei 16 bit inferiori e il canale alfa sarà in quelli superiori. Il verde, rispettivamente, sarà accanto al rosso e il blu accanto all'alfa. E puoi vedere che in 24 bit il formato pixel corrisponde alla struttura RGBTRIPLE dalla tabella dei colori.

Codifica RLE

L'utilizzo della codifica RLE da parte di Microsoft è documentato solo per le profondità di bit 4 e 8. Se utilizzato in BITMAPINFO, il campo Compressione deve contenere 2 (BI_RLE4) alla profondità di bit 4 o 1 (BI_RLE8) con pixel a otto bit. L'altezza del raster deve essere specificata come numero positivo.

Nel formato Windows Bitmap, la codifica RLE può essere paragonata al disegno con semplici comandi. Il disegno parte dal pixel in basso a sinistra (attenzione: nei raster in generale, il pixel in alto a sinistra potrebbe essere più familiare) e procede verso destra e in alto. I pixel al di fuori della dimensione bitmap non vengono disegnati (questo non è menzionato nella documentazione, ma GDI mostra questo comportamento). Le istruzioni RLE consentono di interrompere il disegno di una linea orizzontale, l'intera immagine e anche di spostare il cursore di disegno in un'altra posizione. Di conseguenza, alcuni pixel potrebbero non essere disegnati. La documentazione non fornisce esplicitamente i colori per i pixel non disegnati, per cui l'interpretazione può variare: i pixel mancanti o rimangono trasparenti o acquisiscono un colore con indice 0. Se facciamo la prima ipotesi, allora possiamo dire che 4- e 8 Le modalità -bit sono dovute al supporto implicito della trasparenza RLE, ma questo comportamento non è garantito.

La formazione dell'immagine durante la codifica RLE viene eseguita tramite comandi. Ogni comando deve necessariamente iniziare con un indirizzo pari (allineato a un limite di 16 bit). Ci sono cinque comandi, che sono definiti da una coppia di byte:

Byte 1
(esadecimale)
Byte 2
(esadecimale)
Descrizione
01..FF _ _ 00..FF _ _ Partendo dalla posizione corrente e spostandosi verso destra, disegna tanti pixel quanti sono specificati nel primo byte. I valori per i pixel sono presi dal secondo byte. Nei BMP a 8 bit, l'intero byte è un valore. In 4 bit, viene prelevato a sua volta il nibble più alto, quindi il nibble più basso (quattro bit).
00 00 Sposta il cursore all'inizio (più a sinistra) dell'orizzontale successivo (in alto).
00 01 Smetti di disegnare (fine raggiunto).
00 02 Sposta il cursore a destra e in alto dei valori specificati nei due byte successivi. Il primo byte successivo contiene il valore per lo spostamento orizzontale e il byte successivo contiene il valore per lo spostamento verticale. Entrambi i valori: numeri interi senza segno (non possono essere spostati a sinistra o in basso).
00 03..FF _ _ Dalla posizione attuale e più a destra, disegna i pixel con i valori che seguono questa coppia di byte. Il secondo byte del comando contiene il numero di pixel su cui eseguire il disegno (ovvero pixel, non byte). In un raster a 8 bit, il flusso di byte viene preso così com'è. In 4 bit, i nibble sono già letti: i 4 bit superiori del byte per il primo pixel, i 4 bit inferiori per il successivo e così via dai byte successivi. Questo flusso può terminare con un numero dispari di byte e le istruzioni richiedono l'allineamento a 16 bit. Se ciò accade, viene aggiunto un byte aggiuntivo (il suo contenuto non ha importanza).

Quando viene raggiunto il bordo destro dell'orizzontale, non viene eseguita alcuna traslazione al successivo. Pertanto, è necessario inserire specificamente il comando per terminare la riga. E come puoi vedere dalla tabella, il set di comandi non ti consente di scendere o tornare in orizzontale. Pertanto, puoi interrompere il disegno se viene raggiunto il bordo superiore.

Incorporamento di dati nei formati JPEG e PNG

A partire da Windows 98/ME e 2000/XP, le funzioni di sistema consentono di memorizzare i pixel nei formati JPEG e PNG . Non si sa nulla del grado di supporto di questi due formati da parte del sistema.

Per incorporare un JPEG o un PNG, è necessario reimpostare il campo BitCount in BITMAPINFO e specificare il valore 4 (BI_JPEG) o 5 (PI_PNG) in Compressione. Il valore del campo SizeImage in questo caso sarà uguale alla dimensione del file JPEG o PNG incorporato al posto dei dati pixel così com'è. La larghezza e l'altezza nell'intestazione sono già indicate per l'immagine decodificata. La documentazione non dice direttamente nulla sul segno del campo Altezza per questo caso particolare, ma a quanto pare è necessario annotare un valore negativo [16] .

Risoluzione dell'immagine

Per confrontare i pixel adimensionali con le dimensioni del materiale, vengono utilizzati i campi XPelsPerMeter e YPelsPerMeter. In questi campi, un numero intero indica quanti pixel in questa immagine cadono su un metro lineare, separatamente orizzontalmente (XPelsPerMeter) e verticalmente (YPelsPerMeter). Microsoft ha dichiarato che questi due campi sono un tipo numerico con segno, ma la documentazione non dice nulla sui valori negativi. Non si dice nulla nemmeno sul valore zero, ma è più logico prenderlo per una risoluzione indefinita quando è sconosciuto o non ha valore.

La risoluzione è spesso specificata con riferimento non alle dimensioni metriche, ma in punti per pollice ( DPI / PPI ). Per la traslazione avanti e indietro, viene preso un pollice pari a 25,4 mm (pollice inglese). Formule matematiche per convertire pixel/pollice (PPI) in pixel/metro (PPM) e viceversa:

Se sei interessato a una traduzione intera esatta, vengono fuori le seguenti espressioni:

PPM = (PPI * 5000 + 64) / 127
PPI = (PPM * 127 + 2500) / 5000

Dopo di loro, l'arrotondamento verrà eseguito all'intero più vicino. Se vuoi arrotondare per difetto, non aggiungere metà del divisore. Se vuoi, aggiungi un divisore ridotto di uno.

Di seguito sono riportati i valori PPM precalcolati per alcuni PPI/DPI:

  • 96 ppi ≈ 3780 ppm (per monitor Microsoft)
  • 72 ppi ≈ 2835 ppm ( Apple per monitor)
  • 150 dpi ≈ 5906 ppm
  • 300 dpi ≈ 11811 ppm
  • 600 dpi ≈ 23622 ppm

Spazio colore

Nei campi delle informazioni, il campo principale che specifica lo spazio colore è il campo CSType. I suoi valori consentiti sono riportati nella tabella seguente:

Significato Versione
BITMAPINFO [27]
Nome costante Descrizione
esadecimale Testo
0 (No) quattro LCS_CALIBRATED_RGB Regolazione basata sui valori di Endpoint, GammaRed, GammaGreen e GammaBlue.
73524742 'sRGB' quattro LCS_sRGB Viene utilizzato lo spazio colore sRGB .
57696E20 'Vincere' [28] quattro LCS_WINDOWS_COLOR_SPACE Spazio di sistema predefinito (sRGB).
4C494E4B 'COLLEGAMENTO' 5 PROFILO_LINKED Profilo colore in un altro file.
4D424544 'MBED' 5 PROFILO_INCORPORATO Il profilo colore incluso in questo file.

Microsoft ha dichiarato i valori delle costanti non come valori numerici, ma come valori di testo a quattro caratteri [29] . In questo caso, i codici carattere formano i byte di un valore a 32 bit (il codice ASCII del carattere più a destra è il byte basso, il codice del carattere più a sinistra è il byte alto). Quando si visualizza il contenuto binario di un file come testo, tali valori codificati ASCII verranno visualizzati all'indietro (ad esempio, "KNIL" anziché "LINK").

Endpoint e valori gamma

Il formato Windows Bitmap consente la correzione del colore specificando i punti finali rosso, verde e blu, nonché i valori gamma . Per fare ciò, il campo CSType deve contenere il valore 0 (LCS_CALIBRATED_RGB). I valori correttivi vengono scritti nei campi Endpoints, GammaRed, GammaGreen e GammaBlue (per altri valori CSType questi quattro campi vengono ignorati).

Il campo EndPoints a 36 byte è una struttura CIEXYZTRIPLE composta da tre campi ciexyzRed (endpoint rosso), ciexyzGreen (punto verde) e ciexyzBlue (blu). Questi tre campi sono a loro volta anche strutture CIEXYZ con tre campi ciexyzX, ciexyzY e ciexyzZ di tipo FXPT2DOT30. PXPT2DOT30 è un numero a virgola fissa senza segno a 32 bit con 2 bit alti per la parte intera e 30 bit bassi per la parte frazionaria.

Il valore gamma viene scritto separatamente nei campi corrispondenti per ciascun canale colore: GammaRed (rosso), GammaGreen (verde) e GammaBlue (blu). Nella dichiarazione delle strutture informative, Microsoft ha specificato il tipo DWORD per questi campi. Allo stesso tempo, nel file WinGDI.h, c'è una dichiarazione più appropriata del tipo FXPT16DOT16 (basato sul tipo lungo), che è un numero senza segno a 32 bit con una parte frazionaria nei 16 bit inferiori e un intero parte nei 16 superiori. Va notato che in MSDN, nelle pagine sulle strutture BITMAPV4HEADER e BITMAPV5HEADER , questo è tutto ciò che viene detto. Nell'articolo sulla struttura LOGCOLORSPACE, si dice che il byte alto e basso dovrebbe essere impostato a zero in campi simili (infatti, al posto del formato 16.16, viene utilizzato il formato 8.8, che si trova nel mezzo di un 32 -bit cella) [30] .

Di seguito sono riportati i valori dei quattro campi precedenti in base allo spazio colore sRGB [31] :

Campo Significato
frazionario esadecimale
EndPoints.ciexyzRed.ciexyzX 0,64 28F5C28F
EndPoints.ciexyzRed.ciexyzY 0,33 151EB852
EndPoints.ciexyzRed.ciexyzZ 0.03 01EB851F
EndPoints.ciexyzGreen.ciexyzX 0.30 13333333
EndPoints.ciexyzGreen.ciexyzY 0,60 26666666
EndPoints.ciexyzGreen.ciexyzZ 0.10 06666666
EndPoints.ciexyzBlue.ciexyzX 0,15 0999999A
EndPoints.ciexyzBlue.ciexyzY 0.06 03D70A3D
EndPoints.ciexyzBlue.ciexyzZ 0,79 328F5C29
GammaRed
GammaGreen
GammaBlue
2.20 0002199A [32]

Profilo colore

Nel file BMP, se necessario, è possibile specificare un profilo colore tramite inclusione diretta o collegamento ad un altro file. I profili sono apparsi nella quinta versione di BMP e finora solo qui ci sono campi speciali per loro. I profili colore sono supportati solo nel formato ICC [33] [34] .

Quando si utilizzano i profili colore, è necessario prima specificare i seguenti valori per il campo CSType:

  • 4C494E4B 16 (PROFILE_LINKED) - Se un profilo viene utilizzato in un altro file.
  • 4D424544 16 (PROFILE_EMBEDDED) - se il profilo è incorporato direttamente in BMP.

In ogni caso, il campo ProfileData specifica l'offset del profilo in byte dall'inizio del blocco BITMAPINFO. Se il profilo è integrato, in ProfileSize è necessario specificarne la dimensione in byte (se è collegabile, questo campo deve essere impostato su zero). Indipendentemente dalla variante, Microsoft consiglia di posizionare il profilo dietro i dati dei pixel quando vengono archiviati in un file e immediatamente dopo l'intestazione [35] nella RAM quando si interagisce con le funzioni WinAPI .

Il formato ICC utilizza prevalentemente celle a 32 bit o multipli di questa dimensione di cella nella sua intestazione [36] . In base a ciò, se il profilo è incluso direttamente nel BMP, si consiglia di memorizzarlo nella RAM a un indirizzo multiplo di quattro byte.

Quando il profilo è esterno, invece del suo contenuto, in BMP viene inserita una stringa di testo con il percorso del file. Deve essere nella codifica a byte singolo di Windows 1252 (la codifica standard per le lingue dell'Europa occidentale) e terminare con un byte nullo. La documentazione non dice nulla sui separatori dei componenti del percorso e quindi, molto probabilmente, puoi utilizzare sia le barre sinistra " \ " che "right" "/" . Il percorso può essere sia relativo, sia completo e di rete [35] . E poiché per specificare il percorso viene utilizzata una codifica a byte singolo, non è necessario allineare questa stringa nella RAM.

Preferenze di rendering

Le preferenze di rendering ( English  rendering intents ) sono state introdotte dall'International Color Consortium (International Color Consortium) e determinano le priorità nel caso in cui, spostandosi da un sottospazio colore supportato da un dispositivo ( gamut inglese  ), a un sottospazio di un altro, i colori sono utilizzato nell'immagine, mancante nel target. Esiste anche una definizione dell'ICC che definisce le preferenze di rendering come lo stile di mappatura dei valori di colore da una descrizione dell'immagine all'altra (originale in inglese: "stile di mappatura dei valori di colore da una descrizione dell'immagine all'altra" ) [37 ] . Microsoft ha incluso uno speciale campo Intento nel formato BMP, che può assumere valori completamente secondo la specifica ICC. Pertanto, per maggiori informazioni, si rimanda alla documentazione del consorzio, la cui ultima versione può essere scaricata da color.org [38] . In Microsoft, queste preferenze sono descritte brevemente nell'articolo Intento di rendering su MSDN.

La preferenza è indicata nel campo Intento del blocco BITMAPINFO ed è disponibile solo con la 5a versione dei campi informazioni. I valori possono essere i seguenti:

Significato Nome costante
per BMP
nome
ICC
Nome
Microsoft
Costante
dal file Icm.h
Costante
per DEVMODE
uno LCS_GM_BUSINESS saturazione Grafico INTENT_SATURATION(2) DMICM_SATURATO(1)
2 LCS_GM_GRAPHICS colorimetrico relativo ai media prova INTENT_RELATIVE_COLORIMETRIC(1) DMICM_COLORIMETRICO(3)
quattro LCS_GM_IMAGES percettivo immagine INTENT_PERCEPTUAL(0) DMICM_CONTRAST(2)
otto LCS_GM_ABS_COLORIMETRICO Colorimetrico ICC-assoluto
(colometrico relativo)
Incontro INTENT_ABSOLUTE_COLORIMETRIC(3) DMICM_ABS_COLORIMETRICO(4)

Microsoft ha dichiarato almeno tre insiemi di costanti per questa caratteristica, che differiscono nei loro significati e sono utilizzate in luoghi diversi [39] . Eccoli nel caso in cui sia necessario confrontarli rapidamente. I valori delle costanti precedute da "INTENT_" sono esattamente gli stessi utilizzati nei file di profilo ICC [40] . Le costanti con il prefisso "DMICM_" sono dichiarate nel file WinGDI.h per la struttura DEVMODE. Le costanti "LCS_GM_" utilizzate in BMP sono dichiarate lì e sono destinate principalmente alla struttura LOGCOLORSPACE. Ci sono anche nomi per le proprietà della stampante. Sono simili a quelli nella colonna "Nome Microsoft", ma con "Grafica" e "Immagini".

Il valore predefinito, adatto principalmente per foto e immagini, può essere 4 (LCS_GM_IMAGES). In quanto tale, è raccomandato sia da Microsoft [41] che dall'ICC [42] .

Un esempio di programma C

Il seguente programma apre un file BMP a 24 bit in una XWindow, la profondità del colore deve essere a 32 bit, ma non funziona su una resa cromatica inferiore poiché complica l'esempio:

/* Compilato con la riga: cc -o xtest xtest.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 -lm */
#include <X11/Xlib.h> 
#include <X11/Xutil.h> 
#include <X11/Xatom.h> 
#include <X11/keysym.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <math.h> 
#include "bitmap.h" /* Definizioni dell'intestazione BMP qui come descritto in precedenza in questo articolo (gli struct devono essere compressi a 2 byte!) */ 

statico XImage * CreateImageFromBuffer ( Display * , unsigned char * , int , int );       

principale ( int argc , char * argv [])   
{
    Visualizza * dis ; 
    Vittoria in finestra ; /* La nostra finestra */ 
    Evento XEvent ; /* Sviluppi */ 
    GC gc ; /* Contesto grafico */ 

    Immagine X * immagine ; 
    int n , larghezza , altezza , fd , dimensione ;      
    carattere senza segno * dati ;  
    BITMAPFILEHEADER bmp ; 
    BITMAPINFOHEADER inf ; 
    carattere * buff ; 

    se ( arg < 2 ) {    
	perror ( "usa: xtest file.bmp \n " );
	uscita ( 1 );
    }

  if (( fd = aperto ( argv [ 1 ], O_RDONLY )) == -1 ) {       
        printf ( "Errore durante l'apertura della bitmap \n " );
        uscita ( 1 );
    }

  read ( fd , & bmp , sizeof ( BITMAPFILEHEADER ));  
  read ( fd , & inf , sizeof ( BITMAPINFOHEADER )); 

  larghezza = inf . larghezza doppia ;  
  altezza = inf . bialtezza ;  

    if (( dis = XOpenDisplay ( getenv ( "VISUALIZZA" ))) == NULL ) {      
	printf ( "Impossibile connettere il server X:%s \n " , strerror ( errno )); 
	uscita ( 1 );
    }

    win = XCreateSimpleWindow ( dis , RootWindow ( dis , DefaultScreen ( dis )), 0 , 0 , width , height , 5 ,         
                   BlackPixel ( dis , DefaultScreen ( dis )), WhitePixel ( dis , DefaultScreen ( dis )));   

    XSetStandardProperties ( dis , win , argv [ 1 ], argv [ 0 ], None , argv , argc , NULL );       
    gc = DefaultGC ( dis , DefaultScreen ( dis ));   

 /* A volte questo posto non è riempito nella struttura */
    se ( inf . biSizeImage == 0 ) {    
    /* Calcola la taglia */
     dimensione = larghezza * 3 + larghezza % 4 ;        
     taglia = taglia * altezza ;    
    } altro {  
      dimensione = inf . biSizeImage ;  
     }
    
    buf = malloc ( dimensione );  
    se ( buf == NULL ) {   
	perror ( "malloc" );
	uscita ( 1 );
    }
    printf ( "size =%d byte allocati \n " , size ); 

     /* Sposta all'inizio dell'immagine stessa */
    lseek ( fd , bmp . bfOffBits , SEEK_SET );  

    /* Leggi nel buffer */
    n = letto ( fd , buf , dimensione );    
    printf ( "dimensione =%d byte letti \n " , n ); 

   immagine = CreateImageFromBuffer ( dis , buf , larghezza , altezza );     

   /* Elimina il buffer - non ne abbiamo più bisogno */
   gratuito ( buf );

    XMapWindow ( dis , vinci ); 
    XSelInput ( dis , win , ExposureMask | KeyPressMask );    
    mentre ( 1 ) {  
	XNextEvent ( dis , & evento ); 
	if ( event . xany . window == win ) {    
	    interruttore ( evento . tipo ) {  
	    caso Esporre : 
		XPutImage ( dis , win , gc , image , 0 , 0 , 0 , 0 , image -> width , image -> height );         
		pausa ;

	    caso KeyPress : 
		if ( XLookupKeysym ( & evento . xkey , 0 ) == XK_q ) {     
		    XDestroyImage ( immagine );
		    XChiudiDisplay ( dis );
    	    	    chiudere ( fd );
		    uscita ( EXIT_SUCCESS );
		}
		pausa ;

	    predefinito :
		pausa ;
	    }
	}
    }
}

/* Crea un'immagine X da un file BMP poiché l'immagine BMP è memorizzata capovolta 
* e il ciclo speculare lo risolve */ XImage * CreateImageFromBuffer ( Display * dis , unsigned char * buf , int width , int height ) 
           
{
    int profondità , schermo ;  
    Immagine X * img = NULL ;   
    int io , j ;  
    int numBmpBytes ; 
    size_t numImgBytes ; 
    int32_t * imgBuf ; 
    int ind = 0 ;   
    riga interna ; 
    temperatura interna ; 
    int ih , iw ; /* Numeri di riga e colonna per riflettere */   
    int new_ind ; /* Nuovo indice */  

    schermo = DefaultScreen ( dis );  
    profondità = DefaultDepth ( dis , schermo );   
    temp = larghezza * 3 ;    
    linea = temp + larghezza % 4 ; /* Lunghezza della stringa compreso l'allineamento */       
    numImgBytes = ( 4 * ( larghezza * altezza ));      
    imgBuf = malloc ( numImgBytes );  

    /* Dimensione assegnata per BMP nel file, incluso l'allineamento */
    numBmpBytes = riga * altezza ;    
    for ( io = 0 ; io < numBmpBytes ; io ++ ) {        
	int senza segno r , g , b ;    

	/* Salta il riempimento */
	if ( i >= temp && ( i % linea ) >= temp )         
	    continua ;
	
	b = buf [ io ];  
	io ++ ;
	g = buf [ io ];  
	io ++ ;
	r = buf [ io ];  

	
	/* Calcola un nuovo indice per riflettere verticalmente */
	iw = ind % larghezza ;    
	ih = ind / larghezza ;    
	new_ind = iw + ( altezza - ih - 1 ) * larghezza ;          
	
	imgBuf [ nuovo_ind ] = ( r | g << 8 | b << 16 ) << 8 ;            
	ind ++ ;
    }

    img = XCreateImage ( dis , CopyFromParent , profondità , ZPixmap , 0 , ( carattere * ) imgBuf , larghezza , altezza , 32 , 0 );             
    XInitImage ( img );

    /* L'ordine di bit e byte sul PC dovrebbe essere così */
    img -> ordine_byte = MSBFirst ;  

    img -> bitmap_bit_order = MSBFirst ;  
    ritorno img ; 
}

Vedi anche

  • ICO (File Format)  è un formato correlato di Microsoft per la memorizzazione di icone e cursori del mouse.

Note

  1. 1 2 3 http://fileformats.archiveteam.org/wiki/BMP
  2. https://www.iana.org/assignments/media-types/image/bmp
  3. ^ Leonard S. Tipi di supporti per immagini di Windows  (inglese) - IETF , 2016. - 12 p. doi : 10.17487/RFC7903
  4. http://www.digitalpreservation.gov/formats/fdd/fdd000189.shtml
  5. https://msdn.microsoft.com/en-us/library/dd183391.aspx
  6. ^ Evchenko AI OpenGL e DirectX. Programmazione grafica (per professionisti), 2006, pagina 183.
  7. Vedere la sezione "Osservazioni" dell'articolo " Struttura BITMAPV5HEADER Archiviata il 21 marzo 2014 presso la Wayback Machine " su MSDN.
  8. 1 2 Vedere la sezione "Osservazioni" dell'articolo " Struttura BITMAPINFO Archiviata il 27 febbraio 2014 alla Wayback Machine " su MSDN.
  9. ^ Vedi " Tipi di intestazione bitmap archiviati il ​​22 settembre 2014 in Wayback Machine " su MSDN.
  10. Le informazioni sulla versione sono tratte dalla guida dell'SDK di Microsoft Windows in bundle con Microsoft Visual Studio 2008 e Embarcadero RAD Studio 2010 (sezione dei requisiti negli articoli su queste strutture).
  11. Vedere le sezioni "Requisiti" in " BITMAPCOREHEADER Archiviato il 16 settembre 2014 nella Wayback Machine " e " BITMAPINFOHEADER Archiviato il 19 aprile 2014 nella Wayback Machine " per Windows Mobile 6.5 su MSDN.
  12. Il nome del campo "bV4V4Compression" raddoppiato con "V4" è elencato nella documentazione e nella dichiarazione della struttura nel file WinGDI.h (vedi, ad esempio, " struttura BITMAPV4HEADER archiviata l'11 ottobre 2013 alla Wayback Machine " su MSDN.).
  13. 1 2 3 Microsoft ha annunciato i campi Gamma* come DWORD, ma GDI ha un tipo speciale per tali campi, FXPT16DOT16.
  14. Vedi la sezione "Osservazioni" di BITMAPINFOHEADER Archiviata il 19 aprile 2014 su Wayback Machine (sotto "Windows Mobile 6.5") su MSDN.
  15. Vedere la sezione "Osservazioni" dell'articolo " Costanti del formato pixel dell'immagine archiviate il 4 maggio 2014 nella Wayback Machine " (sotto "GDI+") su MSDN.
  16. 1 2 3 MSDN contiene la frase "Se bV5Height è negativo, indicando un DIB top-down , bV5Compression deve essere BI_RGB o BI_BITFIELDS." (traduzione: "Se bV5Height è negativo, denotando un DIB top-down, allora bV5Compression deve essere BI_RGB o BI_BITFIELDS" ). Potrebbe non essere stato chiarito qui che ciò si applica solo alla codifica RLE, poiché uno degli esempi di disegno di un raster JPEG indica esattamente un'altezza negativa (cercare la riga "bmi.bmiHeader.biHeight" nell'articolo Test di una stampante per JPEG o Supporto PNG Copia archiviata il 14 novembre 2013 su Wayback Machine "su MSDN).
  17. Fai attenzione. Nell'articolo MSDN " BITMAPINFOHEADER Archiviato il 19 aprile 2014 sulla Wayback Machine " per Windows Mobile 6.5, la descrizione del campo biClrUsed contiene la frase "Se biBitCount è uguale a 16 o 32, la tavolozza dei colori ottimale inizia immediatamente dopo le tre maschere DWORD". (traduzione: " Se biBitCount è 16 o 32, la tavolozza dei colori ottimale inizia subito dopo le tre maschere DWORD "). Nello stesso articolo sopra, nella descrizione del campo biCompression, si dice "Specifica che la bitmap non è compressa e che la tabella dei colori è composta da tre maschere di colore DWORD..." e sotto è simile con "è composta da quattro maschere di colore DWORD ” (traduzioni: “Specifica che la bitmap non è compressa e che la tabella dei colori è composta da tre maschere DWORD a colori” e “ è composta da maschere DWORD a quattro colori ”). Informazioni simili sono contenute nell'articolo " Struttura BITMAPINFOHEADER archiviata il 9 febbraio 2014 nella Wayback Machine " per Windows 9x/NT. Tutto questo può essere interpretato in modo tale che a profondità di bit di 16 e 32 dietro i campi di informazione (la struttura BITMAPINFOHEADER) ci siano necessariamente tre maschere a 32 bit per estrarre i valori dei canali di colore. Inoltre, se Compressione contiene 3 (BI_BITFIELDS) o 6 (BI_ALPHABITFIELDS), dopo di esse vengono aggiunte altre tre o quattro maschere simili, che a loro volta occupano la tavola dei colori, rendendo impossibile l'utilizzo di indici a 16 bit di colori ottimali nella logica tavolozza (possibilmente in questo caso in biClrUsed deve essere 6 o 8 e biClrImportant deve essere 0 in modo che le maschere aggiuntive non vengano elaborate accidentalmente come indici nella tavolozza).
    In realtà, le cose sono un po' diverse.
  18. La pagina della documentazione MSDN " Tipi di intestazione bitmap archiviati il ​​22 settembre 2014 presso la Wayback Machine " contiene la frase "I bitmap di 1, 4 o 8 bpp devono avere una tabella di colori con una dimensione massima basata sul bpp". (traduzione: "Le bitmap con una profondità di bit di 1, 4 o 8 devono contenere una tabella di colori con una dimensione massima corrispondente al bit." ). Questo è chiaramente un bug e chi scrive ha applicato le condizioni della struttura CORE, che dovrebbe infatti avere un massimo (vedi la sezione "Osservazioni" nell'articolo " Struttura BITMAPCOREINFO Archiviata il 3 maggio 2015 alla Wayback Machine "), a tutti gli altri versioni delle strutture. In un altro articolo " Struttura BITMAPINFO Archiviata il 24 giugno 2014 presso la Wayback Machine " sulla tabella dei colori si dice "Il numero di voci nell'array dipende dai valori dei membri biBitCount e biClrUsed della struttura BITMAPINFOHEADER". (traduzione: “il numero di elementi nell'array dipende dai valori dei campi biBitCount e biClrUsed della struttura BITMAPINFOHEADER” ), e negli articoli delle strutture versioni 3, 4, 5 (vedi, ad esempio, “ Struttura BITMAPV5HEADER Archiviata l'11 ottobre 2013 sulla Wayback Machine ") nella descrizione del campo BitCount, "il membro bmiColors di BITMAPINFO contiene fino a 256 voci" è scritto ovunque (in modo simile per altri numeri di bit; traduzione della frase: "il Il membro bmiColors BITMAPINFO contiene fino a 256 voci” .
  19. Vedi, ad esempio, le descrizioni dei bit 16 e 32 per il campo bV5BitCount nell'articolo " Struttura BITMAPV5HEADER Archiviata l'11 ottobre 2013 alla Wayback Machine " su MSDN.
  20. Su MSDN e la guida di Microsoft Windows SDK, l'articolo " Struttura BITMAPINFOHEADER archiviata il 9 febbraio 2014 nella Wayback Machine " contiene la frase confusa "Tutti i bit nel pixel non devono essere utilizzati". (traduzione: " Non utilizzare tutti i bit in un pixel "). Questo è un errore di battitura (hanno scritto "avere" invece di "bisogno"), che manca in un blocco simile nell'articolo sulla quinta versione Archiviato l'11 ottobre 2013 sulla Wayback Machine (nella quarta questa frase manca).
  21. Queste informazioni possono essere trovate nella guida di Microsoft Windows SDK fornita con i principali IDE.
  22. Vedere " Costanti di formato pixel immagine archiviate il 4 maggio 2014 su Wayback Machine " su GDI+ su MSDN.
  23. Vedere " PixelFormat Enumeration Archiviata il 23 giugno 2013 su Wayback Machine " su .NET Framework 1.1 su MSDN.
  24. Vedi " Osservazioni archiviate il 24 giugno 2014 in Wayback Machine " nell'articolo "BITMAPINFO" su MSDN.
  25. La documentazione (ad esempio, l'articolo " Struttura BITMAPV5HEADER archiviata l'11 ottobre 2013 nella Wayback Machine " su MSDN) dice che è possibile specificare una dimensione zero con un valore pari a 0 (BI_RGB) per il campo Compressione. Ovviamente questo vale anche per i valori 3 (BI_BITFIELDS) e 6 (BI_ALPHABITFIELDS), poiché fanno la differenza solo nella struttura interna dei pixel, e non nella loro dimensione.
  26. Essenzialmente uno a uno come nella struttura RGBQUAD utilizzata nella tabella dei colori.
  27. Su MSDN, l'articolo " Struttura BITMAPV4HEADER archiviata l'11 ottobre 2013 nella Wayback Machine " menziona un solo valore di campo CSType (LCS_CALIBRATED_RGB). Per un elenco completo dei valori disponibili per le versioni 4 e 5, vedere Using Structures in WCS 1.0 Archiviato il 3 maggio 2015 in Wayback Machine .
  28. C'è un altro spazio dopo "Vinci".
  29. L'uso di questo stile di valori costanti solo nel campo CSType è molto probabilmente il risultato dell'influenza della specifica ICC, in cui ai tag a 32 bit vengono assegnati valori simili nei file di profilo colore . 
  30. Vedere la sezione "Osservazioni" dell'articolo " Struttura LOGCOLORSPACE archiviata il 14 aprile 2013 presso la Wayback Machine " su MSDN.
  31. Numeri presi da " A Standard Default Color Space for the Internet - sRGB Archiviato il 20 agosto 2011 alla Wayback Machine ". Tutti i valori sono stati arrotondati per eccesso se è stato impostato il primo bit destro scartato.
  32. Con il byte basso impostato a zero, il valore sarà 00001A00 16 (arrotondato per eccesso).
  33. Questo formato è descritto nella specifica ICC.1:2010, un collegamento a cui si trova alla fine di questo articolo.
  34. Vedere la sezione "Osservazioni" dell'articolo " Struttura BITMAPV5HEADER Archiviata l'11 ottobre 2013 presso la Wayback Machine " su MSDN.
  35. 1 2 Vedere Using Structures in WCS 1.0 Archiviato il 3 maggio 2015 su Wayback Machine su MSDN.
  36. Vedere la sezione "7.2 Intestazione del profilo" nella specifica ICC.1:2010.
  37. La definizione è data nella specifica ICC.1:2010 nella sezione 3.1.27 a p. 21.
  38. Nella versione 4.3 della specifica (l'ultima al momento della stesura), questo argomento è ampiamente trattato nelle sezioni "0.4 Intento di rendering" (nell'introduzione; p. 8), "6.2 Intento di rendering" (nel contenuto principale; p. 26) e “D. 6 Discussione sugli intenti colorimetrici” (in appendici; p. 109).
  39. Le mappature delle costanti sono prese dal file Icm.h (blocco commentato subito sopra le dichiarazioni della costante "INTENT_").
  40. Vedere la sezione "7.2.15 Campo dell'intento di rendering (byte da 64 a 67)" della specifica ICC.
  41. Vedi la sezione "Picture Intent" dell'articolo " Rendering Intents Archived September 18, 2012 at the Wayback Machine " su MSDN.
  42. Nella specifica in fondo a pagina 41.

Letteratura

Microsoft (MSDN e SDK)

Microsoft Windows SDK  è un kit per sviluppatori che include la guida e i file di inclusione C++. Sul tema di questo articolo sono rilevanti i file WinGDI.h e Icm.h, da cui sono stati presi in primis i valori delle costanti. L'ultima versione di questo kit può essere scaricata gratuitamente dal sito Web di Microsoft (in questo articolo sono state utilizzate le versioni 6.0 e 7.1).

Microsoft non dispone di documentazione specifica separata specificatamente per il formato BMP. Ma le sue strutture e altri elementi sono descritti all'interno del sottosistema GDI. Questa descrizione è nella guida inclusa con l'SDK sopra e anche su MSDN . Inoltre, in quest'ultimo è presente per piattaforme diverse e indipendentemente nella guida di Visual Studio. Nella maggior parte dei casi, le informazioni sono identiche, ma in alcuni punti potrebbero esserci un po' più di fatti (ad esempio, la guida dell'SDK contiene più informazioni sul supporto di Windows).

Per informazioni di base, vedere la guida GDI per le piattaforme Windows 9x e NT. Collegamenti a pagine di questa sezione che fanno riferimento solo al formato e non alle funzioni WinAPI per lavorarci:

Le piattaforme Windows Compact 2013 (CE 6.0) e Mobile 6.5 hanno solo descrizioni di tre strutture, ma per queste piattaforme:

Collegamenti ad altre pagine da MSDN relative al formato BMP:

Altri

La specifica di gestione del colore ICC fornisce informazioni sui profili colore (incluso il formato file ICC) e sulle preferenze di rendering. Tale specifica può essere scaricata dal sito ufficiale del consorzio color.org . Al momento in cui scrivo, l'ultima versione è la 4.3 (dicembre 2010). Collegamenti diretti al PDF dal sito web dell'ICC:

  • Specifica ICC.1:2010 (versione del profilo 4.3.0.0) "Gestione del colore della tecnologia delle immagini - Architettura, formato del profilo e struttura dei dati".
  • Errata alla specifica (errori e refusi trovati; pubblicato il 24 settembre 2013).