Este artigo é sobre a aparência do formato gráfico bmp. Embora este seja um dos formatos mais simples, devido ao facto de existirem muitas variações deste formato, nem todos os pontos são óbvios. Então, pare de derramar água, vamos começar.
Estruturas de formato
O formato bmp (das palavras BitMaP - mapa de bits ou, em russo, matriz de bits) é uma imagem descompactada (principalmente) que é bastante fácil de ler e exibir no sistema operacional Windows, que possui funções API especiais que ajudam.
Primeiro, vamos dar uma representação gráfica dos dados em bmp (foto tirada do MSDN).
No início existe um cabeçalho de arquivo (BITMAPFILEHEADER). É descrito da seguinte forma:
bfType determina o tipo de arquivo. Aqui ele deveria ser BM. Se você abrir qualquer arquivo BMP em um editor de texto (ou melhor ainda, em um editor hexadecimal), verá que os dois primeiros caracteres são BM (da palavra BitMap, como você provavelmente já adivinhou).
bfSizeé o tamanho do próprio arquivo em bytes. A rigor, você deveria calculá-lo (o que é recomendado), mas defini o tamanho do arquivo incorretamente (embora não de propósito :)) e não houve problemas (ACDSee leu sem problemas, meu programa funcionou), mas não recomendo você escreva deliberadamente incorretamente , de repente aparecerá um programa cuidadoso que comparará esse tamanho com o real e decidirá que não é bmp, mas outra coisa. Idealmente, todos os programas, para ter certeza de que se trata de um bmp real e não falso, devem, em primeiro lugar, verificar se bfType contém "BM" (sem aspas) e, em segundo lugar, se bfSize é igual ao tamanho do arquivo.
bfReserved1 e bfReserved2 são reservados e devem ser zero.
bfOffBits. Este é um dos campos mais importantes desta estrutura. Ele mostra onde o próprio bitmap começa em relação ao início do arquivo (ou, como diz o MSDN, “desde o início da estrutura BITMAPFILEHEADER”), que descreve a imagem. Ou seja, para ter certeza de chegar ao início do array você deve escrever:
tag de estrutura typedefBITMAPINFOHEADER
{
DWORD tamanho duplo;
LONGA largura dupla;
LONGO biHeight;
PALAVRA biplanos;
PALAVRA biBitCount;
BiCompressão DWORD;
DWORD biSizeImage;
LONGO biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsado;
DWORD biClrImportante;
) BITMAPINFOHEADER, * PBITMAPINFOHEADER;
biSizeé o tamanho da própria estrutura. Ele precisa ser inicializado da seguinte forma: bih.biSize = sizeof(BITMAPINFOHEADER);
Aqui novamente assumiremos que bih é declarado da seguinte forma: BITMAPINFOHEADER bih;
biWidth e biHeight defina a largura e a altura da imagem em pixels, respectivamente.
biplanos especifica o número de planos. Por enquanto está sempre definido como 1.
biBitCount- Número de bits por pixel. Falaremos mais sobre isso a seguir.
biCompressão indica o tipo de compactação. Não fique surpreso ou assustado com o fato de o bmp sofrer compressão repentina. Pessoalmente, não vi nenhum bmp compactado (mas não estou dizendo que eles não existam). Se não houver compactação, esse sinalizador deverá ser definido como BI_RGB. Neste artigo estamos falando do formato descompactado, então nem vou listar outras flags. Parece que a mesma estrutura é usada nos arquivos JPEG e PNG, pois a partir do Windows 98 surgiram as opções BI_JPEG, que mostra que esta imagem é JPEG e BI_PNG, que é PNG (não sei nada sobre o formato Jpeg, Acabei de tirar essas conclusões com base no que está escrito no MSDN).
biSizeImage indica o tamanho da imagem em bytes. Se a imagem estiver descompactada (ou seja, o campo anterior estiver definido como BI_RGB), então um zero deverá ser escrito aqui. biXPelsPerMeter E biYPelsPerMeter denotam, respectivamente, a resolução horizontal e vertical (em pixels por metro) do dispositivo final no qual o bitmap (raster) será gerado. Um aplicativo pode usar esse valor para selecionar em um grupo de recursos o bitmap mais apropriado para o dispositivo desejado. O fato é que o formato bmp é essencialmente um raster independente de hardware, ou seja, quando a aparência do que é obtido não depende de onde esse raster é projetado (por assim dizer). Por exemplo, uma imagem terá a mesma aparência, independentemente de ter sido desenhada na tela de um monitor ou impressa em uma impressora. Mas a resolução dos aparelhos é diferente, e é justamente para selecionar a imagem mais adequada entre as disponíveis que esses parâmetros são utilizados.
biClrUsado determina o número de cores usadas na tabela. Se esse valor for zero, o raster usará o número máximo de cores permitido pelo valor biBitCount. Isso é relevante apenas para imagens compactadas. Se biClrUsed for diferente de zero e biBitCount for menor que 16, biClrUsed determinará o número atual de cores de mecanismo gráfico ou driver de dispositivo disponíveis. Se biBitCount for maior ou igual a 16, então biClrUsed determinará o tamanho da tabela de cores usada para otimizar a paleta atual do sistema.
biClrImportante- este é o número de cores importantes. Determina o número de cores necessárias para representar o desenho. Se esse valor for 0 (como normalmente é), todas as cores serão consideradas importantes.
Tipos de formato BMP
Todos os tipos de formato bmp condicionalmente pode ser dividido em dois tipos: paleta e não paleta. Ou seja, se a paleta é utilizada em determinado formato ou não. Observe que a paleta pode até estar em formatos sem paleta, mas não é usada lá. Em bmps sem paleta, a cor é calculada diretamente a partir dos bits que vão no arquivo, começando em um determinado local. E nas paletas, cada byte descreve um ou mais pixels, e os valores dos bytes (ou bits) são o índice de cores na paleta. Para começar, fornecerei uma tabela que compara as opções possíveis. O tipo de imagem (paleta ou sem paleta) depende de quantos bits são dados por pixel, ou seja, do valor biBitCount da estrutura BITMAPINFOHEADER.
biBitCount | Formato de paleta ou não paleta | Número máximo possível de cores | Notas | 1 | Paleta | 2 | Uma imagem de paleta de duas cores, veja bem, não necessariamente preto e branco. Se o bit raster (que está logo abaixo) for redefinido (igual a 0), isso significa que a primeira cor da paleta deve estar neste local e, se definida (igual a 1), a segunda. | 4 | Paleta | 16 | Cada byte descreve 2 pixels. Aqui está um exemplo do MSDN. Se o primeiro byte da imagem for 0x1F, então ele corresponde a dois pixels, a cor do primeiro é a segunda cor da paleta (porque a contagem regressiva começa em zero) e o segundo pixel é. a 16ª cor da paleta. | 8 | Paleta | 256 | Uma das opções mais comuns. Mas, ao mesmo tempo, os mais simples. A paleta ocupa um kilobyte (mas é melhor não contar com isso). Um byte é uma cor. Além disso, seu valor é o número da cor na paleta. | 16 | Sem paleta | 2 ^ 16 ou 2 ^ 15 | Esta é a opção mais confusa. Vamos começar com o fato de que ele não tem paleta, ou seja, cada dois bytes (uma palavra WORD) no raster define exclusivamente um pixel. Mas eis o que acontece: existem 16 bits e 3 componentes de cores (vermelho, verde, azul). Mas 16 não quer ser dividido por 3. Portanto, existem duas opções aqui. A primeira é usar não 16, mas 15 bits, então são 5 bits para cada componente de cor. Desta forma podemos usar no máximo 2^15 = 32768 cores e obter um triplo R-G-B = 5-5-5. Mas aí um pedaço inteiro de 16 é desperdiçado em vão. Mas acontece que nossos olhos, entre todas as cores, percebem melhor o verde, então decidimos dar esse pedaço ao componente verde, ou seja, então obtemos o verde. triplo RGB = 5-6-5, e agora podemos usar 2 ^ 16 = 65536 cores. Mas o mais desagradável é que ambas as opções são utilizadas. O MSDN sugere que para distinguir quantas cores são utilizadas, preencha o campo biClrUsed da estrutura BITMAPINFOHEADER com este valor. Para selecionar cada componente você precisa usar as seguintes máscaras. Para formato 5-5-5: 0x001F para componente azul, 0x03E0 para verde e 0x7C00 para vermelho. Para o formato 5-6-5: 0x001F - azul, 0x07E0 - verde e 0xF800 vermelho, respectivamente. | 24 | Sem paleta | 2^24 | E este é o formato mais simples. Aqui, 3 bytes definem 3 componentes de cores. Ou seja, um componente por byte. Simplesmente lemos a estrutura RGBTRIPLE e usamos seus campos rgbtBlue, rgbtGreen, rgbtRed. Eles vão nessa ordem. | 32 | Sem paleta | 2^32 | Aqui, 4 bytes definem 3 componentes. Mas, no entanto, um byte não é usado. Pode ser utilizado, por exemplo, para o canal alfa (transparência). Neste caso, é conveniente ler o raster usando estruturas RGBQUAD, que são descritas a seguir: |
Armazenamento de dados em formato bmp
Bem, agora chegamos à parte mais interessante. Depois das estruturas BITMAPFILEHEADER e BITMAPINFOHEADER vem a paleta. Além disso, se o formato for livre de paleta, pode não estar lá, porém, você não deve contar com isso. O fato é que quando eu estava começando a entender o formato bmp, li em um livro que, supostamente, se o formato não tem paleta, então ele não tem paleta nenhuma. Havia até duas imagens - diagramas de formato: uma com paleta e outra sem. E naquela época eu estava escrevendo um programa que operava diligentemente com arquivos bmp. E tive que converter as imagens recebidas de 256 cores para 24 bits (se houver) em arquivos temporários. E eu simplesmente não criei uma paleta em 24 bits (bfOffBits da estrutura BITMAPFILEHEADER era igual à soma de sizeof(BITMAPFILEHEADER) + sizeof (BITMAPINFOHEADER), e deixei os de 24 bits recebidos inalterados. Com rasters de 256 cores tudo funcionou como deveria, até que não encontrei uma imagem de 24 bits com lixo exibido na parte inferior, em vez da parte necessária, não entendi imediatamente o que estava errado até comparar o tamanho do arquivo original com o. teórico que deveria estar lá se não houvesse paleta. A diferença acabou sendo exatamente 1 KB (havia uma paleta). Portanto, nunca conte se existe uma paleta e não confie em seu tamanho. (embora todas as imagens que encontrei tenham um tamanho de paleta de 256 cores, ou 1Kb), sempre mova o arquivo até o início do raster, usando bfOffBits. A paleta é uma matriz de estruturas RGBQUAD, uma após a outra. nem todas as cores são usadas na paleta (mas apenas, por exemplo, 16), então geralmente 256 campos são alocados para a paleta A 256 * 4 = 1024. 4 é o tamanho da estrutura RGBQUAD, ou seja, o mesmo kilobyte é obtido.
Imediatamente após a paleta vem o próprio raster. É aqui que as coisas ficam mais confusas. Primeiramente, os pixels são descritos aqui conforme escrito na tabela acima, dependendo do formato. E eles próprios podem conter o valor dos componentes de cores (para aqueles sem paleta) ou podem ser índices de uma matriz de paletas. A imagem em si é gravada linha por linha. Em segundo lugar, a imagem parece estar de cabeça para baixo. Ou seja, a linha inferior é escrita primeiro, depois a penúltima linha e assim por diante até o topo. E, em terceiro lugar, conforme escrito, se o tamanho da linha raster não for múltiplo de 4, ela será preenchida com 1 a 3 bytes vazios (zero) para que o comprimento da linha seja um múltiplo do parágrafo. Esta é a coisa mais desagradável. O fato é que para cada formato você tem que ajustar esse número de bytes vazios (embora eu goste de escrever parte da paleta lá, só não quero criar variáveis “zero” extras se esses bytes forem ignorados de qualquer maneira e ninguém precisa deles). Forneço uma tabela com fórmulas que mostram para qual formato quantos bytes devem ser adicionados ao final da linha. Lá, a variável Largura, como você pode imaginar, significa a largura da imagem. Todas essas fórmulas foram estabelecidas experimentalmente. Darei um exemplo apenas para os formatos mais utilizados. Quanto ao resto, você mesmo pode escrever.
Programas de exemplo
Você pode baixar todas as fontes. Não vou escrever muito aqui. Vou apenas fornecer as funções com comentários.
Olá 1. Criando uma imagem em formato bmp.
Aqui é criada uma imagem monocromática. Existem três exemplos de tais funções: criação de bmp de 8, 16 e 24 bits. Darei apenas para 16 bits.
// Vamos criar uma imagem no formato bmp de 16 bits como 5-5-5, que será simplesmente monocromática
void CreateBmp555(char * fname, WORD color)
{
MANIPULAR hArquivo;
DWORDRW;
int eu, j;
//Declara as estruturas necessárias
BITMAPFILEHEADER bfh;
BITMAPINFHEADER bih;
Paleta BYTE[1024]; // Paleta
// Vamos ter uma imagem de 35 x 50 pixels
largura interna = 35;
altura interna = 50;
memset(Paleta, 0, 1024); // Na paleta temos zeros, preencha-os
memset (&bfh, 0 , sizeof (bfh) ) ;
Bfh.bfType = 0x4D42; // Vamos denotar que este é bmp "BM"
bfh.bfOffBits = sizeof (bfh) + sizeof (bih) + 1024; // A paleta ocupa 1 KB, mas não a usaremos
bfh.bfSize = bfh.bfOffBits +
sizeof(cor) * Largura * Altura +
Altura * ((tamanho de (cor) * Largura) % 4 ) ; //Calcula o tamanho do arquivo final
memset (&bih, 0 , sizeof (bih) ) ;
bih.biSize = tamanhode(bih); // É assim que deveria ser
bih.biBitCount = 16; // 16 bits por pixel
bih.biClrUsado = 32768; // Usamos 5-5-5
bih.biCompression = BI_RGB; //Sem compactação
bih.biHeight = Altura;
bih.biWidth = Largura;
bih.biPlanes = 1; //Deve ser 1
// E os campos restantes permanecem 0
HFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hArquivo == INVALID_HANDLE_VALUE)
retornar ;
//Escreve os cabeçalhos
WriteFile (hFile, & bfh, sizeof (bfh) , & RW, NULL ) ;
WriteFile (hFile, & bih, sizeof (bih) , & RW, NULL ) ;
//Escreve a paleta
WriteFile(hArquivo, Paleta, 1024, &RW, NULL);
para (eu = 0; eu<
Height;
i++
)
{
para (j = 0; j<
Width;
j++
)
{
WriteFile (hFile, & color, sizeof (color), & RW, NULL ) ;
}
// Alinha com a borda
WriteFile (hFile, Paleta, (tamanho (cor) * Largura)% 4, & RW, NULL);
}
CloseHandle(hArquivo);
}
cor - cor da imagem. O valor desta variável deve ser preenchido conforme a primeira tabela. Você pode ver a imagem resultante no ACDSee, por exemplo. Acabei de tentar abri-lo no Photoshop, mas descobri que não consigo lê-los neste formato. Mas você pode :).
Exemplo 2. Convertendo uma imagem de 8 bits (256 cores) para 24 bits.
BOOL Convert256To24 (char * fin, char * fout)
{
BITMAPFILEHEADER bfh;
BITMAPINFHEADER bih;
largura interna, altura;
Paleta RGBQUAD[256];
BYTE * inBuf;
RGBTRIPLE * outBuf;
HANDLE hIn, hOut;
DWORDRW;
DWORD Off Bits;
int eu, j;
HIn = CreateFile (fin, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hIn == INVALID_HANDLE_VALUE)
retorna falso;
HOut = CreateFile(fout, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hOut == INVALID_HANDLE_VALUE)
{
CloseHandle(hIn);
retorna falso;
}
//Leia os dados
ReadFile (hIn, & bfh, sizeof (bfh) , & RW, NULL ) ;
ReadFile (hIn, & bih, sizeof (bih) , & RW, NULL );
ReadFile (hIn, Paleta, 256 * sizeof (RGBQUAD) , & RW, NULL ) ;
// Coloca o ponteiro no início do raster
SetFilePointer (hIn, bfh.bfOffBits, NULL, FILE_BEGIN);
Largura = bih.biLargura ;
Altura = bih.biAltura;
OffBits = bfh.bfOffBits;
//Aloca memória
inBuf = novo BYTE [Largura];
outBuf = new RGBTRIPLE [Largura];
//Preenche os cabeçalhos
bfh.bfOffBits = sizeof (bfh) + sizeof (bih); // Não vamos escrever uma paleta
bih.biBitCount = 24;
bfh.bfSize = bfh.bfOffBits + 4 * Largura * Altura + Altura * (Largura% 4); // Tamanho do arquivo
// E o resto permanece inalterado
//Escreve os cabeçalhos
WriteFile (hOut, & bfh, sizeof (bfh) , & RW, NULL ) ;
WriteFile (hOut, & bih, sizeof (bih) , & RW, NULL ) ;
// Vamos começar a converter
para (eu = 0; eu<
Height;
i++
)
{
ReadFile(hIn, inBuf, Largura, & RW, NULL);
para (j = 0; j<
Width;
j++
)
{
outBuf[ j].rgbtRed = Paleta[ inBuf[ j] ] .rgbRed ;
outBuf[ j].rgbtGreen = Paleta[ inBuf[ j] ] .rgbGreen ;
outBuf[ j].rgbtBlue = Paleta[ inBuf[ j] ] .rgbBlue ;
}
WriteFile (hOut, outBuf, sizeof (RGBTRIPLE) * Largura, & RW, NULL ) ;
// Escreve lixo para alinhamento
WriteFile (hOut, Paleta, Largura% 4, & RW, NULL);
SetFilePointer(hIn, (3 * Largura) % 4, NULL, FILE_CURRENT);
}
excluir inBuf;
excluir outBuf;
CloseHandle(hIn);
CloseHandle(hOut);
retorne VERDADEIRO;
}
Os nomes dos arquivos de origem e destino devem ser passados para a função, respectivamente.
A causa mais comum de problemas com a abertura do arquivo BMP é simplesmente uma falta de aplicativos apropriados instalados em seu computador. Nesse caso, basta localizar, baixar e instalar um aplicativo que sirva arquivos no formato BMP - tais programas estão disponíveis abaixo.
Sistema de pesquisa
Insira a extensão do arquivo
Ajuda
Dica
Observe que alguns dados codificados de arquivos que nosso computador não lê às vezes podem ser visualizados no Bloco de Notas. Desta forma leremos fragmentos de texto ou números - Vale a pena verificar se este método também funciona no caso de arquivos BMP.
O que fazer se o aplicativo da lista já estiver instalado?
Muitas vezes, o aplicativo instalado deve ser automaticamente associado ao arquivo BMP. Se isso não acontecer, o arquivo BMP poderá ser associado manualmente com sucesso ao aplicativo recém-instalado. Basta clicar com o botão direito no arquivo BMP e selecionar a opção “Escolher o programa padrão.” Então você precisa selecionar a opção “Visualizar” e encontrar seu aplicativo favorito. As alterações inseridas devem ser aprovadas através da opção “OK”.
Programas que abrem o arquivo BMP
janelas
Mac OS
Por que não consigo abrir um arquivo BMP?
Os problemas com arquivos BMP também podem ter outras causas. Às vezes, mesmo a instalação de software no seu computador que suporta arquivos BMP não resolve o problema. A impossibilidade de abrir e trabalhar com o arquivo BMP pode também ser causada por:
Associações inapropriadas de arquivos BMP nas entradas do registro
- corrupção do arquivo BMP que abrimos
- Infecção de arquivo BMP (vírus)
- poucos recursos de computador
- drivers desatualizados
- remover a extensão BMP do registro do Windows
- instalação incompleta de um programa que suporta a extensão BMP
A correção desses problemas deve resultar na abertura e no trabalho gratuitos com arquivos BMP. Caso seu computador ainda apresente problemas com arquivos, você precisará da ajuda de um especialista que determinará a causa exata.
Meu computador não mostra extensões de arquivo, o que devo fazer?
Nas configurações padrão do sistema Windows, o usuário do computador não vê a extensão do arquivo BMP. Isso pode ser alterado com sucesso nas configurações. Basta ir ao “Painel de Controle” e selecionar “Visualizar e Personalização”. Então você precisa ir em "Opções de pasta" e abrir "Exibir". Na aba “Visualizar” existe a opção “Ocultar extensões de tipos de arquivos conhecidos” - você deve selecionar esta opção e confirmar a operação clicando no botão “OK”. Neste ponto, as extensões de todos os arquivos, incluindo BMP, devem aparecer classificadas por nome de arquivo.
Anúncio
Formato de arquivo de imagem BMP Raster
BMP (arquivo bitmap, formato de arquivo bitmap independente de dispositivo) são arquivos bitmap usados para armazenar imagens bitmap digitais separadamente do dispositivo de exibição. Este tipo de arquivo foi usado anteriormente no Microsoft Windows e OS/2. O termo "raster" vem da ideia dos programadores de bitmap. As imagens BMP geralmente são descompactadas ou compactadas sem perdas (por exemplo, usando ZIP ou RAR - devido à presença de dados redundantes no arquivo). Hoje, o JPG é o formato de imagem preferido – principalmente devido ao grande tamanho do arquivo BMP, que pode causar problemas ou atrasos no download, envio ou upload de arquivos.
Informações técnicas sobre arquivos BMP
Os arquivos BMP são armazenados como imagens 2D de vários tamanhos, cores e profundidades de cores sem compactação de dados, perfis de cores ou canais alfa. As imagens BMP são salvas em formatos de bitmap independente de dispositivo (DIB), o que significa que a imagem possui cores em vez de especificações do sistema. Isso explica por que algumas imagens BMP parecem diferentes em computadores diferentes. As imagens BMP podem ser visualizadas em qualquer dispositivo, incluindo telas de computador e televisão. A falta de patentes tornou este tipo de imagem um formato popular para uma ampla gama de dispositivos.
Informações adicionais sobre o formato BMP
Extensão de arquivo | .bmp |
Categoria de arquivo | |
Arquivo de exemplo | (2,7 MiB) (487,85 KiB) |
Programas relacionados | Adobe Photoshop MS Pintura Editor de fotos da Microsoft pincel |