Cet article explique à quoi ressemble le format graphique bmp. Bien qu’il s’agisse de l’un des formats les plus simples, tous les points ne sont pas évidents en raison du fait qu’il existe de nombreuses variantes de ce format. Alors arrêtez de verser de l’eau, commençons.
Formater les structures
Le format bmp (des mots BitMaP - bit map ou, en russe, bit array) est une image non compressée (principalement) qui est assez facile à lire et à afficher dans le système d'exploitation Windows, qui possède des fonctions API spéciales qui aident.
Tout d'abord, donnons une représentation graphique des données en bmp (image tirée de MSDN).
Au début il y a un en-tête de fichier (BITMAPFILEHEADER). Il est décrit comme suit :
bfType détermine le type de fichier. Ici, il devrait être BM. Si vous ouvrez un fichier BMP dans un éditeur de texte (ou mieux encore, dans un éditeur hexadécimal), vous verrez que les deux premiers caractères sont BM (du mot BitMap, comme vous l'avez probablement déjà deviné).
bfTaille est la taille du fichier lui-même en octets. À proprement parler, vous devriez le calculer (ce qui est recommandé), mais j'ai mal défini la taille du fichier (mais pas exprès :)) et il n'y a eu aucun problème (ACDSee a lu sans problème, mon programme a fonctionné), mais je ne vous recommande pas écrivez-le délibérément de manière incorrecte, tout à coup un programme consciencieux apparaîtra qui comparera cette taille avec la taille réelle et décidera que ce n'est pas du bmp, mais autre chose. Idéalement, tous les programmes, afin de s'assurer qu'il s'agit d'un vrai bmp et non d'un faux, devraient, d'une part, vérifier que bfType contient "BM" (sans guillemets), et, d'autre part, que bfSize est égal à la taille du fichier.
bfReserved1 et bfReserved2 sont réservés et doivent être nuls.
bfOffBits. C'est l'un des domaines les plus importants de cette structure. Il montre où commence le bitmap lui-même par rapport au début du fichier (ou, comme le dit MSDN, "à partir du début de la structure BITMAPFILEHEADER"), qui décrit l'image. Autrement dit, pour être sûr d'arriver au début du tableau, vous devez écrire :
typedef struct tagBITMAPINFOHEADER
{
DWORD biTaille ;
Bilargeur LONGUE ;
LONG biHauteur ;
Biplans WORD ;
MOT biBitCount ;
BiCompression DWORD ;
DWORD biTailleImage ;
LONG biXPelsPerMeter ;
BiYPelsPerMètre LONG ;
DWORD biClrUtilisé ;
DWORD biClrImportant ;
) BITMAPINFOHEADER, * PBITMAPINFOHEADER ;
biTaille est la taille de la structure elle-même. Il doit être initialisé comme suit : bih.biSize = sizeof(BITMAPINFOHEADER);
Ici encore nous supposerons que bih est déclaré comme suit : BITMAPINFOHEADER bih;
biLargeur et biHauteur définissez respectivement la largeur et la hauteur de l'image en pixels.
biplans précise le nombre d'avions. Pour l'instant, il est toujours réglé sur 1.
biBitCount- Nombre de bits par pixel. Nous en parlerons davantage ci-dessous.
biCompression indique le type de compression. Ne soyez pas surpris ou effrayé que bmp subisse soudainement une compression. Personnellement, je n'ai pas vu plus d'un bmp compressé (mais je ne dis pas qu'ils n'existent pas). S'il n'y a pas de compression, cet indicateur doit être défini sur BI_RGB. Dans cet article, nous parlons du format non compressé, je ne listerai donc même pas d’autres indicateurs. Il semble que la même structure soit utilisée dans les fichiers JPEG et PNG, car à partir de Windows 98 sont apparues les options BI_JPEG, qui montrent que cette image est JPEG et BI_PNG, qu'elle est PNG (je ne connais rien au format Jpeg, Je viens de tirer ces conclusions sur la base de ce qui est écrit dans MSDN).
biTailleImage indique la taille de l'image en octets. Si l'image n'est pas compressée (c'est-à-dire que le champ précédent est défini sur BI_RGB), alors un zéro doit être écrit ici. biXPelsParMètre Et biYPelsParMètre désignent respectivement la résolution horizontale et verticale (en pixels par mètre) du périphérique final sur lequel le bitmap (raster) sera généré. Une application peut utiliser cette valeur pour sélectionner parmi un groupe de ressources le bitmap le plus approprié pour le périphérique souhaité. Le fait est que le format BMP est essentiellement un raster indépendant du matériel, c'est-à-dire lorsque l'apparence de ce qui est obtenu ne dépend pas de ce sur quoi ce raster est projeté (pour ainsi dire). Par exemple, une image aura la même apparence, qu’elle soit dessinée sur un écran de contrôle ou imprimée sur une imprimante. Mais la résolution des appareils est différente, et c'est précisément pour sélectionner l'image la plus adaptée parmi celles disponibles que ces paramètres sont utilisés.
biClrUtilisé détermine le nombre de couleurs utilisées à partir du tableau. Si cette valeur est zéro, le raster utilise le nombre maximum de couleurs autorisé par la valeur biBitCount. Ceci ne concerne que les images compressées. Si biClrUsed est différent de zéro et biBitCount est inférieur à 16, alors biClrUsed détermine le nombre actuel de couleurs de moteur graphique ou de pilote de périphérique disponibles. Si biBitCount est supérieur ou égal à 16, alors biClrUsed détermine la taille de la table de couleurs utilisée pour optimiser la palette système actuelle.
biClrImportant- c'est le nombre de couleurs importantes. Détermine le nombre de couleurs nécessaires pour représenter le dessin. Si cette valeur est 0 (comme c’est généralement le cas), alors toutes les couleurs sont considérées comme importantes.
Types de formats BMP
Tous types de format bmp conditionnellement peut être divisé en deux types : palette et non-palette. Autrement dit, si la palette est utilisée ou non dans un format donné. Veuillez noter que la palette peut même être dans des formats sans palette, mais elle n'y est pas utilisée. Dans les bmps sans palette, la couleur est calculée directement à partir des bits qui vont dans le fichier, à partir d'un certain endroit. Et dans les palettes, chaque octet décrit un ou plusieurs pixels, et les valeurs d'octets (ou bits) sont l'index de couleur dans la palette. Pour commencer, je vais fournir un tableau qui compare les options possibles. Le type d'image (avec palette ou sans palette) dépend du nombre de bits donnés par pixel, c'est-à-dire de la valeur biBitCount de la structure BITMAPINFOHEADER.
biBitCount | Format palette ou non palette | Nombre maximum de couleurs possible | Remarques | 1 | Palette | 2 | Une image de palette bicolore, remarquez, pas nécessairement en noir et blanc. Si le bit raster (qui est juste en dessous) est réinitialisé (égal à 0), cela signifie que la première couleur de la palette doit être à cet endroit, et si elle est définie (égale à 1), alors la seconde. | 4 | Palette | 16 | Chaque octet décrit 2 pixels. Voici un exemple tiré de MSDN. Si le premier octet de l'image est 0x1F, alors il correspond à deux pixels, la couleur du premier est la deuxième couleur de la palette (car le compte à rebours commence à zéro) et le deuxième pixel est la 16ème couleur de la palette. | 8 | Palette | 256 | L'une des options les plus courantes. Mais en même temps, les plus simples. La palette occupe un kilo-octet (mais il vaut mieux ne pas compter dessus). Un octet correspond à une couleur. De plus, sa valeur est le numéro de couleur dans la palette. | 16 | Pas de palette | 2^16 ou 2^15 | C'est l'option la plus déroutante. Commençons par le fait qu'il est sans palette, c'est-à-dire que tous les deux octets (un mot WORD) dans le raster définissent de manière unique un pixel. Mais voici ce qui se passe : il y a 16 bits, et il y a 3 composantes de couleur (Rouge, Vert, Bleu). Mais 16 ne veut pas être divisé par 3. Il y a donc deux options ici. La première consiste à utiliser non pas 16, mais 15 bits, puis il y a 5 bits pour chaque composante de couleur. De cette façon, nous pouvons utiliser un maximum de 2^15 = 32768 couleurs et obtenir un triple R-G-B = 5-5-5. Mais ensuite, un tout petit peu sur 16 est gaspillé en vain. Mais il se trouve que nos yeux, parmi toutes les couleurs, perçoivent mieux le vert, nous avons donc décidé de donner ce bit à la composante verte, c'est-à-dire que nous obtenons alors le triple R-G-B = 5-6-5, et maintenant nous pouvons utiliser 2^16 = 65536 couleurs. Mais le plus désagréable, c'est que les deux options sont utilisées. MSDN suggère que pour distinguer le nombre de couleurs utilisées, remplissez le champ biClrUsed de la structure BITMAPINFOHEADER avec cette valeur. Pour sélectionner chaque composant, vous devez utiliser les masques suivants. Pour le format 5-5-5 : 0x001F pour la composante bleue, 0x03E0 pour la verte et 0x7C00 pour la rouge. Pour le format 5-6-5 : 0x001F - composants bleus, 0x07E0 - composants verts et 0xF800 rouges, respectivement. | 24 | Pas de palette | 2^24 | Et c'est le format le plus simple. Ici, 3 octets définissent 3 composants de couleur. Autrement dit, un composant par octet. Nous lisons simplement la structure RGBTRIPLE et utilisons ses champs rgbtBlue, rgbtGreen, rgbtRed. Ils vont dans cet ordre. | 32 | Pas de palette | 2^32 | Ici, 4 octets définissent 3 composants. Cependant, un octet n’est pas utilisé. Il peut être utilisé par exemple pour le canal alpha (transparence). Dans ce cas, il est pratique de lire le raster à l'aide des structures RGBQUAD, qui sont décrites comme suit : |
Stockage des données au format BMP
Eh bien, arrivons maintenant à la partie la plus intéressante. Après les structures BITMAPFILEHEADER et BITMAPINFOHEADER vient la palette. De plus, si le format est sans palette, il se peut qu'il ne soit pas là, mais il ne faut pas compter dessus. Le fait est que lorsque je commençais tout juste à comprendre le format bmp, j'ai lu dans un livre que, soi-disant, si le format est sans palette, alors il n'a pas de palette du tout. Il y avait même deux images - diagrammes de format : une avec une palette, l'autre sans. Et à cette époque, j'écrivais un programme qui fonctionne avec diligence avec des fichiers BMP. Et j'ai dû convertir les images entrantes de 256 couleurs en 24 bits (le cas échéant) en fichiers temporaires. Et je n'ai tout simplement pas créé de palette en 24 bits (bfOffBits de la structure BITMAPFILEHEADER était égal à la somme de sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER), et j'ai laissé les 24 bits entrants inchangés. Avec des rasters de 256 couleurs, tout fonctionnait comme il se doit, jusqu'à ce que je ne tombe pas sur une image 24 bits affichant des déchets en bas au lieu de la partie requise. Je n'ai pas immédiatement compris ce qui n'allait pas. Jusqu'à ce que je compare la taille du fichier d'origine avec celui théorique qui aurait dû être là s'il n'y avait pas de palette. La différence s'est avérée être exactement de 1 Ko (exactement 1024 octets). Il y avait une palette. Par conséquent, ne comptez jamais sur l'existence d'une palette et ne vous fiez pas à sa taille (bien que toutes les images que j'ai rencontrées avaient une taille de palette de 256 couleurs, soit 1 Ko), déplacez-vous toujours dans le fichier jusqu'au début du raster, en utilisant bfOffBits. La palette est un tableau de structures RGBQUAD se succédant. Même si toutes les couleurs ne sont pas utilisées dans la palette (mais seulement, par exemple, 16), alors souvent 256 champs sont encore alloués à la palette. Et 256 * 4 = 1024, où 4 est la taille de la structure RGBQUAD, c'est-à-dire ce même kilo-octet est obtenu.
Immédiatement après la palette vient le raster lui-même. C’est là que les choses deviennent plus confuses. Tout d'abord, les pixels sont décrits ici comme écrit dans le tableau ci-dessus, en fonction du format. Et ils peuvent eux-mêmes contenir la valeur des composants de couleur (pour ceux sans palette), ou ils peuvent être des index d'un tableau de palettes. L'image elle-même est enregistrée ligne par ligne. Deuxièmement, la situation semble inversée. C'est-à-dire que la ligne du bas est écrite en premier, puis l'avant-dernière ligne, et ainsi de suite jusqu'au sommet. Et troisièmement, comme indiqué, si la taille de la ligne raster n'est pas un multiple de 4, elle est alors complétée par 1 à 3 octets vides (zéro) afin que la longueur de la ligne soit un multiple du paragraphe. C'est la chose la plus désagréable. Le fait est que pour chaque format, vous devez ajuster ce nombre d'octets vides (même si j'aime y écrire une partie de la palette, je ne veux tout simplement pas créer de variables « zéro » supplémentaires si ces octets sont de toute façon ignorés et que personne en a besoin). Je fournis un tableau avec des formules indiquant pour quel format combien d'octets doivent être ajoutés à la fin de la ligne. Là, la variable Largeur, comme vous pouvez le deviner, signifie la largeur de l'image. Toutes ces formules ont été établies expérimentalement. Je ne donnerai un exemple que pour les formats les plus utilisés. Pour le reste, vous pouvez l'écrire vous-même.
Exemples de programmes
Vous pouvez télécharger toutes les sources, je n’écrirai pas grand-chose ici. Je vais juste donner les fonctions avec des commentaires.
Bonjour 1. Création d'une image au format bmp.
Ici, une image monochromatique est créée. Il existe trois exemples de telles fonctions : création de bmp 8, 16 et 24 bits. Je ne donnerai que pour 16 bits.
// Créons une image au format bmp 16 bits type 5-5-5, qui sera simplement monochromatique
void CreateBmp555(char * fname, couleur WORD)
{
MANIPULER hFichier ;
DWORDRW ;
int je, j;
// Déclare les structures nécessaires
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih ;
Palette OCTET[1024] ; // Palette
// Ayons une image de 35 x 50 pixels
int Largeur = 35 ;
int Hauteur = 50 ;
memset(Palette, 0, 1024); // Dans la palette nous avons des zéros, remplissez-les
memset (&bfh, 0 , taille de (bfh) ) ;
Bfh.bfType = 0x4D42 ; // Notons qu'il s'agit de bmp "BM"
bfh.bfOffBits = taillede (bfh) + taillede (bih) + 1024 ; // La palette occupe 1 Ko, mais nous ne l'utiliserons pas
bfh.bfSize = bfh.bfOffBits +
taille de (couleur) * Largeur * Hauteur +
Hauteur * ((taille de (couleur) * Largeur) % 4 ) ; // Calcule la taille du fichier final
memset (& bih, 0 , taille de (bih) ) ;
bih.biSize = taillede(bih); // Voilà comment il est censé être
bih.biBitCount = 16 ; // 16 bits par pixel
bih.biClrUsed = 32768 ; // Nous utilisons 5-5-5
bih.biCompression = BI_RVB ; // Sans compression
bih.biHeight = Hauteur ;
bih.biWidth = Largeur ;
bih.biPlanes = 1 ; // Devrait être 1
// Et les champs restants restent 0
HFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
si (hFichier == INVALID_HANDLE_VALUE)
retour ;
// Ecrit les en-têtes
WriteFile (hFile, & bfh, sizeof (bfh) , & RW, NULL ) ;
WriteFile (hFile, & bih, sizeof (bih) , & RW, NULL ) ;
// Ecrire la palette
WriteFile(hFichier, Palette, 1024, &RW, NULL);
pour (je = 0 ; je<
Height;
i++
)
{
pour (j = 0 ; j<
Width;
j++
)
{
WriteFile (hFile, & color, sizeof (color) , & RW, NULL ) ;
}
// Aligner avec la bordure
WriteFile (hFile, Palette, (sizeof (color) * width) % 4 , & RW, NULL ) ;
}
CloseHandle(hFichier) ;
}
couleur - couleur de l'image. La valeur de cette variable doit être renseignée selon le premier tableau. Vous pouvez par exemple visualiser l'image obtenue dans ACDSee. J'ai juste essayé de l'ouvrir dans Photoshop, mais il s'est avéré qu'il ne peut pas les lire dans ce format. Mais vous pouvez :).
Exemple 2. Conversion d'une image du format 8 bits (256 couleurs) en 24 bits.
BOOL Convert256To24 (char * fin, char * fout)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih ;
int Largeur, Hauteur ;
Palette RVBQUAD[ 256 ] ;
OCTET * inBuf ;
RVBTRIPLE * outBuf ;
POIGNÉE hIn, hOut ;
DWORDRW ;
DWORD DésactivéBits ;
int je, j;
HIn = CreateFile (fin, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL) ;
si (hIn == INVALID_HANDLE_VALUE)
retourner FAUX ;
HOut = CreateFile(fout, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
si (hOut == INVALID_HANDLE_VALUE)
{
CloseHandle(hIn);
retourner FAUX ;
}
// Lire les données
ReadFile (hIn, & bfh, sizeof (bfh) , & RW, NULL ) ;
ReadFile (hIn, & bih, sizeof (bih) , & RW, NULL ) ;
ReadFile (hIn, Palette, 256 * taille de (RGBQUAD) , & RW, NULL ) ;
// Place le pointeur au début du raster
SetFilePointer (hIn, bfh.bfOffBits, NULL, FILE_BEGIN) ;
Largeur = bih.biWidth ;
Hauteur = bih.biHauteur ;
OffBits = bfh.bfOffBits ;
// Allouer de la mémoire
inBuf = new BYTE [Largeur] ;
outBuf = nouveau RGBTRIPLE [Largeur] ;
// Remplir les en-têtes
bfh.bfOffBits = taillede (bfh) + taillede (bih) ; // N'écrivons pas de palette
bih.biBitCount = 24 ;
bfh.bfSize = bfh.bfOffBits + 4 * Largeur * Hauteur + Hauteur * (Largeur % 4 ) ; // Taille du fichier
// Et le reste reste inchangé
// Ecrit les en-têtes
WriteFile (hOut, & bfh, sizeof (bfh) , & RW, NULL ) ;
WriteFile (hOut, & bih, sizeof (bih) , & RW, NULL ) ;
// Commençons la conversion
pour (je = 0 ; je<
Height;
i++
)
{
ReadFile (hIn, inBuf, Largeur et RW, NULL ) ;
pour (j = 0 ; j<
Width;
j++
)
{
outBuf[ j].rgbtRed = Palette[ inBuf[ j] ] .rgbRed ;
outBuf[ j].rgbtGreen = Palette[ inBuf[ j] ] .rgbGreen ;
outBuf[ j].rgbtBlue = Palette[ inBuf[ j] ] .rgbBlue ;
}
WriteFile (hOut, outBuf, sizeof (RGBTRIPLE) * Largeur, & RW, NULL ) ;
// Écrit des déchets pour l'alignement
WriteFile (hOut, Palette, Largeur % 4 , & RW, NULL ) ;
SetFilePointer(hIn, (3 * Largeur) % 4, NULL, FILE_CURRENT) ;
}
supprimer inBuf ;
supprimer outBuf ;
CloseHandle(hIn);
CloseHandle(hOut);
retourner VRAI ;
}
Les noms des fichiers source et destination doivent être transmis respectivement à la fonction.
La cause la plus fréquente des problèmes liés à l'ouverture du fichier BMP est simplement le manque d'applications appropriées installées sur votre ordinateur. Dans ce cas, il suffit de rechercher, télécharger et installer une application qui sert des fichiers au format BMP - ces programmes sont disponibles ci-dessous.
Système de recherche
Entrez l'extension du fichier
Aide
Indice
Veuillez noter que certaines données codées provenant de fichiers que notre ordinateur ne lit pas peuvent parfois être visualisées dans le Bloc-notes. De cette façon, nous lirons des fragments de texte ou des chiffres. Il convient de vérifier si cette méthode fonctionne également dans le cas des fichiers BMP.
Que faire si l'application de la liste est déjà installée ?
Souvent, l'application installée doit automatiquement se lier à un fichier BMP. Si cela ne se produit pas, le fichier BMP peut être associé manuellement avec l'application nouvellement installée. Faites simplement un clic droit sur le fichier BMP, puis dans la liste disponible, sélectionnez l'option "Choisir le programme par défaut". Ensuite, vous devez sélectionner l'option « Afficher » et trouver votre application préférée. Les modifications saisies doivent être approuvées à l'aide de l'option "OK".
Programmes qui ouvrent le fichier BMP
les fenêtres
MacOS
Pourquoi ne puis-je pas ouvrir un fichier BMP ?
Les problèmes avec les fichiers BMP peuvent également avoir d'autres causes. Parfois, même installer un logiciel sur votre ordinateur prenant en charge les fichiers BMP ne résoudra pas le problème. L'impossibilité d'ouvrir et de travailler avec le fichier BMP peut aussi être causée par:
Associations de fichiers BMP inappropriées dans les entrées de registre
- corruption du fichier BMP que nous ouvrons
- Infection du fichier BMP (virus)
- trop peu de ressources informatiques
- pilotes obsolètes
- suppression de l'extension BMP du registre Windows
- installation incomplète du programme supportant l'extension BMP
La résolution de ces problèmes devrait permettre d'ouvrir et d'utiliser librement les fichiers BMP. Si votre ordinateur rencontre toujours des problèmes avec les fichiers, vous devez faire appel à un expert qui déterminera la cause exacte.
Mon ordinateur n'affiche pas les extensions de fichiers, que dois-je faire ?
Dans les paramètres système standard de Windows, l'utilisateur de l'ordinateur ne voit pas l'extension du fichier BMP. Cela peut être modifié avec succès dans les paramètres. Allez simplement dans le « Panneau de configuration » et sélectionnez « Affichage et personnalisation ». Ensuite, vous devez aller dans « Options des dossiers » et ouvrir « Affichage ». Dans l'onglet "Affichage", il y a une option "Masquer les extensions des types de fichiers connus" - vous devez sélectionner cette option et confirmer l'opération en cliquant sur le bouton "OK". À ce stade, les extensions de tous les fichiers, y compris BMP, devraient apparaître triées par nom de fichier.
Annonce
Format de fichier d'image raster BMP
BMP (fichier bitmap, format de fichier bitmap indépendant du périphérique) sont des fichiers bitmap utilisés pour stocker des images bitmap numériques séparément du périphérique d'affichage. Ce type de fichier était auparavant utilisé dans Microsoft Windows et OS/2. Le terme « raster » vient de l'idée des programmeurs d'un bitmap. Les images BMP sont généralement non compressées ou compressées sans perte (par exemple, en utilisant ZIP ou RAR - en raison de la présence de données redondantes dans le fichier). Aujourd'hui, JPG est le format d'image préféré - principalement en raison de la grande taille des fichiers BMP, ce qui peut entraîner des problèmes ou des retards lors du téléchargement, de l'envoi ou du téléchargement de fichiers.
Informations techniques sur les fichiers BMP
Les fichiers BMP sont stockés sous forme d'images 2D de différentes tailles, couleurs et profondeurs de couleurs sans compression de données, profils de couleur ou canaux alpha. Les images BMP sont enregistrées au format bitmap indépendant du périphérique (DIB), ce qui signifie que l'image a des couleurs plutôt que des spécifications du système. Cela explique pourquoi certaines images BMP semblent différentes sur différents ordinateurs. Les images BMP peuvent être visualisées sur n’importe quel appareil, y compris les écrans d’ordinateur et de télévision. L’absence de brevets a fait de ce type d’image un format populaire pour une large gamme d’appareils.
Informations complémentaires sur le format BMP
Extension de fichier | .bmp |
Catégorie de fichier | |
Exemple de fichier | (2,7 Mo) (487,85 Ko) |
Programmes associés | Adobe Photoshop MS Peinture Éditeur de photos Microsoft Pinceau |