ID do artigo: 81498 - Última revisão: sexta-feira, 11 de fevereiro de 2005 - Revisão: 2.5

DIBs e seus usos

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Recolher tudo

Sumário

A seguir é o texto do artigo "DIBs e seus usa". Este artigo está disponível no formato de arquivo Ajuda na biblioteca do Software Microsoft juntamente com o texto apresentado abaixo.

Mais Informações

Os seguintes arquivos estão disponíveis para download no Centro de download da Microsoft:


Dibs2.exe (http://download.microsoft.com/download/platformsdk/article/3.1/w31/en-us/dibs2.exe)
Para obter informações adicionais sobre como baixar arquivos de suporte da Microsoft, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
119591  (http://support.microsoft.com/kb/119591/EN-US/ ) Como obter arquivos de suporte da Microsoft a partir de serviços online
Microsoft examinou esse arquivo em busca de vírus. Microsoft utilizou o mais recente software de detecção de vírus que estava disponível na data em que o arquivo foi publicado. O arquivo é armazenado em servidores com segurança avançada que ajudam a evitar qualquer alteração não autorizada no arquivo. Este artigo descreve o conceito de (bitmap independente de dispositivo) DIB de definição e a estrutura para a API que o utiliza. Incluído é um aplicativo pequeno exemplo que ilustra alguns dos métodos mais comuns de usar DIBs para exibir e manipular imagens digitais. Funções abordadas são GetDIBits() , SetDIBits() , CreateDIBitmap() , SetDIBitsToDevice() , StretchDIBits() e CreateDIBPatternBrush() . Este artigo não aborda com paletas DIBs.

VISÃO GERAL

Um bitmap independente de dispositivo (DIB) é um formato usado para definir bitmaps independentes de dispositivo em várias resoluções de cor. O principal objetivo de DIBs é permitir que bitmaps a ser movida de um dispositivo para outro (portanto, a parte independente de dispositivo do nome do). Um DIB é um formato externo, ao contrário de um bitmap dependente de dispositivo, que aparece no sistema como um objeto de bitmap (criado por um aplicativo usando CreateBitmap() , CreateCompatibleBitmap() , CreateBitmapIndirect() ou CreateDIBitmap() ). Um DIB normalmente é transportado em metarquivos (normalmente usando a função StretchDIBits() ), os arquivos bmp e a área de transferência (formato de dados CF_DIB).

Um DIB consiste em duas partes: os próprios bits e um cabeçalho que descreve o formato dos bits. O cabeçalho contém o formato de cor, uma tabela de cores e o tamanho do bitmap. O formato DIB atual oferece suporte a quatro resoluções de cor: 1 bit, 4 bits, 8 bits e 24 bits. Em DIBs de 1 bit, 4-bits e 8 bits, os pixels são definidos por índices (da resolução de bit apropriado) na tabela de cores; 24 bits pixels são descritos como valores de 24 bits, de 1 byte cada, para vermelho, verde e azul. As funções DIB são:
   GetDIBits:           Translates a device-dependent bitmap into the DIB
                        format

   SetDIBits:           Translates a DIB's information into device-
                        dependent form

   CreateDIBitmap:      Creates a device-dependent bitmap initialized with
                        DIB information

   SetDIBitsToDevice:   Sets a DIB directly to the output surface

   StretchDIBits:       Moves a rectangle from the DIB to a rectangle on
                        the destination surface, stretching or compressing
                        as necessary

   CreateDIBPatternBrush:   Creates a pattern brush using a DIB for the
                            bitmap description
				

INDEPENDÊNCIA DE DISPOSITIVO - NOVIDADES-BOM PARA?

Não foi possível nas versões do anteriormente o ambiente de gráfico do Microsoft Windows que 3.0 transferência de bitmaps de cor de um dispositivo para outro. Com DIBs, cada dispositivo exibe a imagem para a extensão de sua resolução de cor. Um aplicativo pode armazenar uma imagem no formato DIB e, em seguida, exibi-la, independentemente do dispositivo de saída; um aplicativo não precisa criar uma versão de cada imagem para cada tipo de dispositivo.

Essa capacidade de transferência de imagem pode ser usada para imprimir imagens de meio-tom. Por exemplo, a função StretchDIBits() pode passar um DIB diretamente para um driver de impressora inteligente. Considerando as informações de quatro cores da imagem em vez de simplesmente uma versão monocromática (o método tradicional), o driver pode usar meios-tons para imprimir uma imagem realista.

Porque o formato DIB publicamente está definido, um aplicativo pode manipulá-lo imediatamente. Na verdade, um aplicativo pode criar uma imagem sem qualquer interação com o Windows. Se o Windows não possui um primitivo de desenho, o aplicativo pode simulá-lo diretamente para o DIB em vez de usar os primitivos de interface (GDI) de dispositivo de elementos gráficos existentes. Infelizmente, em Windows versões 3.0 e 3.1, GDI não é possível executar operações de saída diretamente para uma DIB.

FORMATOS DE ARQUIVO BMP

A extensão de arquivo de um arquivo DIB de Windows é BMP. O arquivo consiste em uma estrutura BITMAPFILEHEADER seguida de DIB propriamente dito. Infelizmente, porque a estrutura BITMAPFILEHEADER nunca na verdade é passada para a API, não cada aplicativo que gera os arquivos bmp preenche a estrutura de dados com cuidado. Para adicionar a essa confusão, a definição "correta" da estrutura está em conflito com a documentação. Corretamente, a estrutura de dados contém os seguintes campos:
   bfType              A WORD that defines the type of file. It must be
                       'BM'.

   bfSize              A DWORD that specifies the size of the file in
                       bytes. The Microsoft Windows Software Development
                       Kit (SDK) documentation claims otherwise. To be on
                       the safe side, many applications calculate their
                       own sizes for reading in a file.

   bfReserved1,
   bfReserved2         WORDs that must be set to 0.

   bfOffBits           A DWORD that specifies the offset from the

                       beginning of the BITMAPFILEHEADER structure to the
                       start of the actual bits. The DIB header
                       immediately follows the file header, but the
                       actual image bits need not be placed next to the
                       headers in the file.
				
DIB O cabeçalho imediatamente segue a estrutura BITMAPFILEHEADER .

Para um exemplo de código que lê um arquivo BMP, consulte o programa de exemplo.

O cabeçalho DIB

O cabeçalho, na verdade, consiste em duas partes adjacentes: o cabeçalho apropriado e a tabela de cores. Ambos são combinados na estrutura de BITMAPINFO , que é o que esperar todas as APIs de DIB.

O Windows versão 3.0 oferece suporte a duas variedades de cabeçalhos: BITMAPINFOHEADER e BITMAPCOREHEADER. Se possível, os aplicativos devem usar somente BITMAPINFOHEADERs. A definição de BITMAPCOREHEADER baseada na definição de bitmap do Gerenciador de apresentação versão 1.1 e é suportada para compatibilidade.

Durante uma operação de configuração DIB, a maioria dos campos já estão preenchidos por quem gerado de DIB. No entanto, fazer uma chamada GetDIBits() , fornece mais controle. A maneira como o cabeçalho é preenchido para esta operação define o DIB resultante, particularmente sua resolução de cor.

BITMAPINFOHEADER contém os seguintes campos:
   biSize              Should be set to sizeof(BITMAPINFOHEADER). This
                       field defines the size of the header (minus the
                       color table). If a new DIB definition is added, it
                       is identified by a new value for the size. This
                       field is also convenient for calculating a pointer
                       to the color table, which immediately follows the
                       BITMAPINFOHEADER.

   biWidth, biHeight   Define the width and the height of the bitmap in
                       pixels. They are DWORD values for future
                       expansion, and the code in Windows versions 3.0
                       and 3.1 ignores the high word (which should be set
                       to 0).

   biPlanes            Should always be 1. All DIB definitions rely on
                       biBitCount for color resolution definition.

   biBitCount          Defines the color resolution (in bits per pixel)
                       of the DIB. Only four values are valid for this
                       field: 1, 4, 8, and 24. New resolutions (16 bit,
                       for example) may be added in the future, but for
                       now only these four define a valid DIB. Choosing the
                       appropriate value when doing a GetDIBits is
                       discussed below. When performing a Set operation,
                       the value should already be defined for the bits.

   biCompression       Specifies the type of compression. Can be one of
                       three values: BI_RGB, BI_RLE4, or BI_RLE8. The most
                       common and useful choice, BI_RGB, defines a DIB in
                       which all is as it seems. Each block of biBitCount
                       bits defines an index (or RGB value for 24-bit
                       versions) into the color table. The other two
                       options specify that the DIB is stored (or will be
                       stored) using either the 4-bit or the 8-bit run
                       length encoding (RLE) scheme that Windows
                       supports. The RLE formats are especially useful
                       for animation applications and also usually
                       compress the bitmap. BI_RGB format is recommended
                       for almost all purposes. RLE versions, although
                       possibly smaller, are slower to decode, not as
                       widely supported, and extremely painful to band
                       properly.

   biSizeImage         Should contain the size of the bitmap proper in
                       bytes. I say "should" because the field is not
                       necessarily filled in. A call to GetDIBits to
                       generate a DIB fills in this field, but a DIB
                       created manually by an application might not have
                       this filled in. Calculating the size of a bitmap
                       is not hard:

                       biSizeImage = ((((biWidth * biBitCount) + 31)
                                      & ~31) >> 3) * biHeight;

                       The crazy roundoffs and shifts account for the
                       bitmap being DWORD-aligned at the end of every
                       scanline. When nonzero, this field tells an
                       application how much storage space the DIB's bits
                       need. The biSizeImage field really becomes useful
                       when dealing with an RLE bitmap, the size of which
                       depends on how well the bitmap was encoded. If an
                       RLE bitmap is to be passed around, the biSizeImage
                       field is essential.

   biXPelsPerMeter,
   biYPelsPerMeter     Define application-specified values for the
                       desirable dimensions of the bitmap. This
                       information can be used to maintain the physical
                       dimensions of an image across devices of different
                       resolutions. GDI never touches these fields. When
                       not filled in, they should both be set to 0.

   biClrUsed           Provides a way for getting smaller color tables.
                       When this field is set to 0, the number of colors
                       in the color table is based on the biBitCount
                       field (1 indicates 2 colors, 4 indicates 16, 8
                       indicates 256, and 24 indicates no color table). A
                       nonzero value specifies the exact number of colors
                       in the table. So, for example, if an 8-bit DIB
                       uses only 17 colors, then only those 17 colors
                       need to be defined in the table, and biClrUsed is
                       set to 17. Of course, no pixel can have an index
                       pointing past the end of the table.

                       Note: This field cannot be used during a GetDIBits
                       operation. GDI always fills a full-size color
                       table. The field is therefore more useful for
                       post-processing operations, when an application
                       trims down the contents of the DIB. If nonzero for
                       a 24-bit DIB, it indicates a table that the
                       application can use for color reference.

   biClrImportant      Specifies that the first x colors of the color
                       table are important to the DIB. If the rest of the
                       colors are not available, the image still retains
                       its meaning in an acceptable manner.
                       biClrImportant is purely for application use; GDI
                       does not touch this value. When this field is set
                       to 0, all the colors are important, or rather,
                       their relative importance has not been computed.
				
a tabela de cores segue imediatamente as informações de cabeçalho. Nenhuma tabela de cores está definida para DIBs de 24 bits. A tabela consiste em uma matriz de estruturas de dados RGBQUAD. (A tabela para o formato BITMAPCOREINFO é criada com a estrutura de dados RGBTRIPLE .) Bytes de vermelhos, verdes e azuis estão em ordem inversa (posição de troca vermelho com azul) da convenção de Windows. Este é outro leftover de compatibilidade do Gerenciador de apresentação.

O tamanho da tabela cor depende do valor biBitCount (e pode ser substituído usando o campo biClrUsed ; consulte acima):
   if (!(nNumColors = biClrUsed))
   {

     if (biBitCount != 24)
          nNumColors = 1 << biBitCount;

   }
   nTableSize = nNumColors * sizeof(RGBQUAD);
				
mais DIBs circulando no momento tem biClrUsed definido como 0, mas se qualquer bashing DIB completo é planejado, ele é uma boa idéia defini-la corretamente. Se biClrUsed for diferente de zero, uma tabela de cores com DIBs de 24 bits, é possível. GDI não usa essa tabela de cores, mas o aplicativo pode usá-lo para determinar as importantes cores usadas no DIB.

Todas as funções DIB incluem um parâmetro wUsage, que pode afetar a definição de tabela de cores. Este artigo evita usando paletas DIBs e assim pressupõe que wUsage é sempre definido como DIB_RGB_COLORS e que a tabela de cores, portanto, é sempre composto de valores RGB. Quando DIB_PAL_COLORS é usado, a tabela de cores consiste em valores de WORD que são índices na paleta de lógica selecionada no momento. (Este tópico é discutido em detalhes no artigo "Usando DIBs com paletas").

Formatos de bits

O cabeçalho define o formato dos bits, mas todos os formatos de compartilham as seguintes regras:
  • Verificação de cada linha é alinhado em DWORD. A verificação de linha é armazenado em buffer para alinhamento; o buffer não é necessariamente 0.
  • As verificações de linha são armazenadas de cabeça para baixo, com a primeira verificação (verificação 0) na memória que está sendo a verificação mais abaixo na imagem. (Consulte a Figura 1). Este é outro artefato de compatibilidade do Gerenciador de apresentação. GDI automaticamente inverte a imagem durante as operações Set and Get. Figura 1. (Imagem incorporada mostrando representações de memória e de tela.)
  • Limites do segmento de 64 K não são respeitados; verificações de linha podem atravessar tais limites (ao contrário o formato de bitmap dependente de dispositivo que é armazenado em buffer para limites de 64 K).
Cada formato tem as seguintes especificações:
  • 1 bit DIBs são armazenadas usando cada bit como um índice na tabela de cores. O bit mais significativo é o pixel mais à esquerda.
DIBs de 4 bits são armazenadas com cada 4 bits que representa um índice para a tabela de cores. Nibble mais significativo é o pixel mais à esquerda.
  • DIBs de 8 bits são mais fáceis armazenar porque cada byte é um índice.
  • DIBs de 24 bits tem a cada 3 bytes que representa uma cor, usando o mesmo ordering como a tabela de cores. Esse formato é especialmente difícil durante o processamento porque um limite de 64 K pode existir no meio de um triplo de cor--uma condição difícil que deve ser manipulado com cuidado.

USANDO A API DE DIB

GetDIBits() e SetDIBits()

Essas duas funções são usadas para converter bitmaps independentes de dispositivo em bitmaps dependentes de dispositivo e vice-versa. SetDIBits() converte um DIB para bitmap dependente de dispositivo, e GetDIBits() gera um DIB de um bitmap dependente de dispositivo.

O driver de dispositivo referenciado por hDC passado para ambas as chamadas executa a conversão real. Alguns drivers de dispositivo talvez não tenha essa funcionalidade (por exemplo, um driver de versão 2.0 do Windows ou um driver primitivo de versão 3.0 do Windows). Nesse caso, GDI simula a conversão, mas apenas no formato monocromático--informações de cores são convertidas em preto e branco. Para maior parte, entretanto, isso não é uma preocupação. Todos os drivers de vídeo self-respecting oferecem suporte a essa funcionalidade e apenas alguns drivers de impressora não fornecerem a tradução, geralmente monocromáticos drivers para o qual simulações GDI suficiente.

GetDeviceCaps(hDC, RASTERCAPS) retorna um valor WORD com sinalizadores definidos indicando qual DIB funções suporta a driver. RC_DI_BITMAP indica suporte GetDIBits() e SetDIBits() , RC_DIBTODEV indica suporte de SetDIBitsToDevice() e RC_STRETCHDIB indica suporte de StretchDIBits() . Pode ser simulada qualquer função que não tem suportada, embora as simulações geralmente não sejam tão útil quanto a coisa real (principalmente porque informações de cores serão perdidas). Um dispositivo pode não conseguir oferecer suporte a funcionalidade completa, mesmo se for definido um pouco. Por exemplo, um dispositivo foi suporte StretchDIBits, mas apenas para stretches integrais. Infelizmente, um aplicativo não tem como determinar a integridade da implementação. Nesses casos, a GDI simula a função.

Os parâmetros são os mesmos para GetDIBits() e SetDIBits() :
GetDIBits(hDC, hBitmap, nStartScan, nNumScans, lpBits, lpBitmapInfo,
wUsage)

SetDIBits(hDC, hBitmap, nStartScan, nNumScans, lpBits, lpBitmapInfo,
wUsage)

hDC            The device context (DC) responsible for the translation
               operation. hDC must be compatible with the hBitmap
               parameter.

hBitmap        The device-dependent bitmap from which (Get) or to
               which (Set) the DIB will be translated. Because of how
               the simulation code operates, this bitmap should not be
               currently selected into any DC.

nStartScan,
nNumScans      Define the contents of lpBits. For example, a StartScan
               of 5 indicates that lpBits points to the fifth scan of
               the DIB. A NumScans of 14 indicates that lpBits points
               to 14 scans of the DIB. Normally, nStartScan is set to
               0 and nNumScans is set to biHeight to denote that the
               whole DIB is pointed to by lpBits.

lpBits         The actual bitmap of the DIB. The pixel information is
               pointed to by this parameter.

lpBitmapInfo   The header (with color table) defining the DIB. The
               height and width in this header must match the height
               and width of the hBitmap parameter (the translation is
               always 1-to-1). The color resolution of the DIB need
               not match that of hBitmap.

wUsage         For the purposes of this article, assume this to be
               DIB_RGB_COLORS, indicating RGB colors in the color
               table.
				
usando SetDIBits() é razoavelmente simples. Um DIB é obtido em algum lugar (por exemplo, da área de transferência ou de um arquivo de disco) e é convertido a um objeto bitmap, que, em seguida, pode ser selecionado em um controlador de domínio e blted para a tela de exibição. Esta é a maneira mais simples para exibir um DIB.

Observação Para muitas impressoras que podem fazer meios-tons, esse método não é preferencial; StretchDIBits (discutido no seguinte) é muito mais útil.

A seguir está uma exibição simples de DIB para um controlador de domínio (com nenhum tratamento de erros):
   HBITMAP hBitmap;
   HDC hMemDC;

   hBitmap = CreateCompatibleBitmap(hDC, (WORD)lpInfo->biWidth,
          lpInfo->(WORD)biHeight);

   hMemDC = CreateCompatibleDC(hDC);
   SetDIBits(hDC, hBitmap, 0, (WORD)lpInfo->biHeight, lpBits,

          lpBitmapInfo, DIB_RGB_COLORS);

   hBitmap = SelectObject(hMemDC, hBitmap);
   BitBlt(hDC, 0, 0, (WORD)lpInfo->biWidth, (WORD)lpInfo->biHeight,

          hMemDC, 0, 0, SRCCOPY);

   DeleteObject(SelectObject(hMemDC, hBitmap));
   DeleteDC(hMemDC);
				
usando GetDIBits() é mais complexo porque o aplicativo pode escolher que tipo de DIB para gerar. O tamanho do bitmap origem regula as dimensões do DIB (uma parte pode ser extraída por blting em um bitmap menor), mas o aplicativo necessário pode ditar a resolução de cores.

Para GetDIBits() funcione corretamente, o aplicativo precisa definir os seguintes campos no cabeçalho:
   biSize = sizeof(BITMAPINFOHEADER)
   biWidth = (width of the bitmap)
   biHeight = (height of the bitmap)
   biPlanes = 1
   biBitCount = [desired color resolution (1, 4, 8, or 24)]
   biCompression = BI_RGB (For RLE information, see below.)
				
também, o espaço alocado para a tabela de cores deve ser suficiente para manter uma tabela em tamanho normal:
   if (biBitCount != 24)

     nSizeTable = (1 << biBitCount) * sizeof(RGBQUAD)

   else

     nSizeTable = 0;
				
o espaço alocado para lpBits também precisa ser grande o suficiente para armazenar nNumScans de dados. A chamada preencha os seguintes campos da estrutura:
  • biSizeImage = tamanho em bytes dos dados DIB
  • Tabela de cores (para o caso de não-24 bits) é preenchida com cores apropriadas
  • lpBits é preenchida com dados DIB
Se for chamado GetDIBits() com lpBits definido como NULL, não bits são retornados; somente biSizeImage e a tabela de cores são preenchidos. Essa opção é útil para DIBs com RLE e não é interessante para DIBs não codificado.

Objetivos do aplicativo para o DIB determinam qual resolução de cores para escolher. A abordagem comum é gerar um DIB que preserva as informações cores do bitmap dependente de dispositivo de origem. Escolher um resultados de resolução menor perda de informações de cores, que é geralmente indesejável. Sempre usar resolução de 24 bits não é desnecessária, no entanto, porque isso adiciona nenhuma resolução de cores mais se a fonte tiver 8 bits ou menor resolução.
   BITMAP bm;

   // get information on bitmap
   GetObject(hBitmap, sizeof(BITMAP), (LPVOID)&bm);

   BitmapRes = bm.bmPlanes * bm.bmBitsPixel;
   if (BitmapRes == 1)

     biBitCount = 1;

   else if (BitmapRes <= 4)

     biBitCount = 4;

   else if (BitmapRes <= 8)

     biBitCount = 8;

   else

     biBitCount = 24;
				
cálculo de resolução do bitmap deve levar em conta que alguns bitmaps dependentes de dispositivo são planar (notavelmente EGA e VGA). DIBs, por outro lado, são sempre "incluídos pixel," com plano apenas 1 por pixel (biPlanes = 1).

Os parâmetros nStartScan e nNumScans (residue de compatibilidade do Gerenciador de apresentação) são projetados para ser usado para faixas. Se não há memória suficiente está disponível para carregar o DIB inteira na memória em uma parte, lpBits podem ser feitas aponte para apenas uma parte dos bits. Considere o exemplo a seguir:
   #define MAXREAD 5
   WORD ReadXScans(LPSTR, WORD);   // Read up to X scans; return
                                   // NumRead.
   LPSTR lpBits;                   // Points to a block of memory for
                                   // MAXREAD scans.
   LPBITMAPINFOHEADER lpInfo;
   WORD nStart, nNumRead;

   for (nStart = 0; nStart >= (WORD)lpInfo->biHeight; )
   {

     nNumRead = ReadXScans(lpBits, MAXREAD);
     SetDIBits(hDC, hBitmap, nStart, nNumRead,
          lpBits, lpInfo, DIB_RGB_COLORS);
     nStart += nNumRead;

   }
				
definir o código leva a faixa de determinado, converte-o e coloca a faixa convertida no local adequado, estatísticas em todos os horários para a vantagem - para baixo a natureza dos DIBs. Observe como biHeight não altera a qualquer momento porque a faixa é colocada no bitmap com base na altura do bitmap completo. nStart se baseia a altura da imagem completa (definida por biHeight).

CreateDIBitmap()

O código a seguir demonstra CreateDIBitmap() chamada com o caso comum:
   hBitmap = CreateDIBitmap(hDC, lpInfo, CBM_INIT, lpBits, lpInfo,
                            wUsage);
				
isso equivale a:
   hBitmap = CreateCompatibleBitmap(hDC, (WORD)lpInfo->biWidth,

             (WORD)lpInfo->biHeight);

   SetDIBits(hDC, hBitmap, 0, (WORD)lpInfo->biHeight, lpBits, lpInfo,
             wUsage);
				
implementação do GDI ignora a parte SetDIBits() se o terceiro parâmetro não for definido com o sinalizador CBM_INIT. Esta função torna para atalho boa codificação de conversão de DIB para bitmap dependente de dispositivo.

SetDIBitsToDevice()

SetDIBitsToDevice() permite que um aplicativo definir um DIB diretamente para uma superfície de dispositivo. Como essa função é um holdout de desenvolvimento inicial, sua interface não é tão elegante pode ser. StretchDIBits() é uma função muito mais poderosa que SetDIBitsToDevice() . StretchDIBits() faz tudo que SetDIBitsToDevice() faz e tem uma interface melhor. SetDIBitsToDevice() é limitado a forma como trata metarquivos porque ele não se adapta e faixas com os parâmetros nStartScan e nNumScans é não-trivial na melhor das hipóteses. StretchDIBits() não permite a faixa.

O código a seguir executa a funcionalidade SetDIBitsToDevice() no bitmap completo (sem faixa) usando StretchDIBits:
   StretchDIBits(hDC, x, y, (WORD)lpInfo->biWidth,

          (WORD)lpInfo->biHeight, 0, 0, (WORD)lpInfo->biWidth,
          (WORD)lpInfo->biHeight, lpBits, lpInfo, DIB_RGB_COLORS,
          SRCCOPY)
				
supondo que nStartScan é definido como 0 e que nNumScans é definida como lpInfo-> biHeight (ou seja, nenhuma faixa), a função é basicamente um BitBlt com SRCCOPY como o ROP e com um DIB como a fonte. SrcX e SrcY são no espaço do DIB e, portanto, cabeça para baixo em relação ao controlador de domínio (Y = 0 está na parte inferior da imagem).

Lidando com a cabeça para baixo DIB é complicado ao fazer uma configuração parcial. Por exemplo, se quiser que um aplicativo obter a parte inferior terceiro de uma DIB que é w por pixels h para o dispositivo em (x, y), a chamada deve se parecer com o seguinte:
   SetDIBitsToDevice(hDC, x, y, w, h/3, 0, h/3, 0,

          (WORD)lpInfo->biHeight, lpBits, lpInfo, DIB_RGB_COLORS);
				
um bitmap dependente de dispositivo teria um SrcY de h 2/3 para a parte inferior em terceiro lugar, mas com a vantagem - sistema de DIB, um SrcY de h/3 pontos para o local correto em relação ao Windows coordenadas.

StretchDIBits()

Esta função é o queridinho todos para exibir um DIB na superfície de um dispositivo. É especialmente interessante para metafiling e para impressão, para o qual a capacidade para alongar é importante.

Um orifício crítico na implementação atual de StretchDIBits() é que StretchDIBits() é suportada por drivers de impressora e não por muitos drivers de vídeo. Portanto, usar essa função repetidamente para alongar um DIB para a tela é significativamente mais lento que usando SetDIBits (para obter um bitmap dependente de dispositivo) seguido por chamadas StretchBlt() repetidas.

A implementação desta função no GDI é muito simples. Se o driver de dispositivo pode manipular a chamada propriamente dita, ele faz. Caso contrário e a chamada é 1 a 1 e o dispositivo oferece suporte SetDIBitsToDevice() , a chamada é convertida para uma chamada SetDIBitsToDevice() para o driver. (Isso só funciona com SRCCOPY como o ROP.) Se nenhum desses métodos for possível, CreateDIBitmap() é usado para fazer uma versão dependentes de dispositivo do bitmap e StretchBlt é chamado para fazer o trabalho real.

Os parâmetros para StretchDIBits() são basicamente a mesma do StretchBlt() (com o hDC fonte substituído por lpBits e lpInfo). Esta função não possui o nStartScan e os parâmetros nNumScans das outras funções DIB, portanto, lpBits sempre aponta para a primeira verificação do DIB.

Ao usar esta função para algo diferente de bitmap completo stretches, lembre-se que todos as coordenadas de origem (aquelas relacionadas ao DIB) estejam em um sistema de cabeça para baixo. A função será adequadamente inverter a imagem, mas o retângulo de origem é definido com Y = 0 na parte inferior e extensões indo. Felizmente, as coordenadas x usam as mesmas convenções de como o Windows.

Drivers de impressora que têm suporte para essa funcionalidade (por exemplo, PSCRIPT e HPPCL) geralmente usam um algoritmo de meio-tom para imagens coloridas boa de saída. Portanto, manter DIBs na resolução de cor significativo mais alta possível (geralmente 8 bits) é desejável mesmo se o dispositivo de saída for monocromática, pois estão ainda útil para saída boa as informações de cores. Infelizmente, a maioria dos drivers de impressora não suportam qualquer ROP diferente SRCCOPY.

CreateDIBPatternBrush()

Essa função permite que um aplicativo para criar um pincel padrão especificando um DIB em vez de um bitmap dependente de dispositivo, como as usadas na função CreatePatternBrush() . Um pincel criado usando esta função é usado como qualquer outro Pincel. O DIB será transformado em um bitmap dependente de dispositivo em tempo de SelectObject() para uso pelo dispositivo. Esse pincel é semelhante a um pincel de padrão para o dispositivo.

DIBS NA ÁREA DE TRANSFERÊNCIA

Dois mecanismos básicos para o posicionamento DIBs na área de transferência estão usando o formato de dados CF_DIB ou colocando o DIB em um metarquivo e usando o formato de dados CF_METAFILEPICT.

O formato CF_DIB usa um DIB compactada, no qual os bits siga imediatamente após o cabeçalho e a tabela de cores. Ao ler ou criar um DIB compactada, um aplicativo deve calcular corretamente o tamanho da tabela de cores para garantir que os bits estejam no local adequado. Porque todas as funções DIB esperam que o DIB como dois ponteiros, uma para o cabeçalho e outra para os bits, o ponteiro de bits deve ser calculado antes de usar. (Para cor computações de tamanho de tabela, consulte o exemplo de código na descrição da tabela de cores acima).

A maneira mais simples para colocar um DIB em um metarquivo é usar StretchDIBits() :
   hMetaDC = CreateMetaFile((LPSTR) NULL));
   StretchDIBits(hMetaDC, 0, 0, biWidth, biHeight, 0, 0, biWidth,

          biHeight, lpBits, lpInfo, DIB_RGB_COLORS, SRCCOPY);

   hMetafile = CloseMetaFile(hMF);
				
essa abordagem gera um metarquivo que, quando reproduzido exibe DIB para o destino. Esse método também dimensiona a imagem para ajustar o esquema de mapeamento atual, se necessário. Usando metarquivos para transferência permite até mesmo que os aplicativos não estão cientes de DIB para colar o conteúdo da área de transferência sem perder as informações de DIB.

FORMATOS DE RLE

Quando o campo biCompression no cabeçalho do DIB é definido como qualquer BI_RLE4 (para biBitCount = 4) ou BI_RLE8 (para biBitCount = 8), a imagem foi codificado de comprimento de execução. Uma descrição dos esquemas de codificação pode ser encontrada no "Microsoft Windows Software Development Kit referência volume 2," na seção "BITMAPINFOHEADER" de "tipos de dados e estruturas" capítulo. O esquema básico envolve compactando vários pixels horizontalmente adjacentes, idênticos em uma codificação de execução. Por exemplo, 10 pixels de índice de cor 17 são codificados como uma seqüência de comprimento 10 do índice 17. Códigos para o final de verificação e delta move também são fornecidos, no qual um X e um deslocamento de Y são fornecidos para o próximo pixel.

Esse tipo de codificação geralmente compacta o bitmap e também é útil para criação de animações tipo sprite, na qual apenas uma pequena parte de uma imagem é alterado em cada quadro. Os recursos de animação são realizados usando códigos de delta para limitar o número de pixels, na verdade, sendo definida. Pixels ignorados pelo mover delta são esquerda inalteradas.

As principais limitações do RLE DIBs são que um aplicativo pode facilmente determinar o tamanho do bitmap em bytes nem aponte para uma determinada verificação de linha sem decodificar o bitmap da primeira verificação. O campo biSizeImage é útil para solucionar o problema primeiro. Decodificação, codificação e geralmente manipular a RLE formato é mais lenta e mais complicado do que o formato (BI_RGB) noncompressed. Alguns aplicativos--por exemplo, Paintbrush--se recusar a ler RLE DIBs. Embora todas as APIs aceitá-las, RLE DIBs provavelmente não se tornará um formato universalmente com suporte. Além disso, devido a raridade relativa desses formatos, alguns drivers de dispositivo podem não ter totalmente testado suporte para os processos de codificação e decodificação.

Para gerar um DIB RLE, GetDIBits() é chamado com biCompression definido para o tipo desejado de codificação. A quantidade de memória necessária para armazenar os bits não é calculada facilmente. Se GetDIBits() é chamado com lpBits definido como NULL, a quantidade de memória necessária para os bits será retornada em biSizeImage. Uma chamada subseqüente com lpBits apontando para um bloco de memória corretamente dimensionado retorna um bitmap codificado.

Convertendo um DIB RLE em um formulário dependentes de dispositivo não requer nenhum processamento especial. Qualquer uma das funções conjunto pode ser usado normalmente com um cabeçalho contendo biSizeImage adequado e biCompression valores para coincidir com os bits.

LIMITAÇÕES DE DIBS

Provavelmente a maior limitação DIBs é que eles são mais lentos do que bitmaps de dispositivo dependente. Convertendo DIBs em um formulário dependentes de dispositivo antes de realmente possam ser exibidos requer processamento extra, resultando em uma sobrecarga adicional. Em um mundo ideal, seria tão rápido quanto um BitBlt() StretchDIBits() um-para-1. Essa velocidade permitiria que um aplicativo para operar com eficiência no território do bitmap lógico, com cor completo e o acesso total a cada pixel, independentemente das limitações do dispositivo físico.

DIBs baseadas em um sistema de coordenadas cabeça para baixo em relação ao Windows, tornando a codificação um pouco frustrantes e não intuitivo. Lembrar esta quirkiness sempre deve ajudar limite o número de iterações necessários para obter bitmaps corretamente alinhados.

Você pode obter quatro cores usando DIBs de 24 bits, mas eles são muito lentas decodificar, ler e gravar. Isso é especialmente verdadeiro em dispositivos de paleta de 8 bits, no qual conversão literalmente sejam minutos. Além disso, o tamanho grande de DIBs de 24 bits torna um pouco complicado para uso geral.

PROBLEMAS RELACIONADOS AO DIB NO WINDOWS VERSÃO 3.0

Gravação de metarquivo de chamadas StretchDIBits() que usam BITMAPCOREHEADER faz com que um Emirados Árabes Unidos. Converta todos os cabeçalhos para o estilo BITMAPINFO para evitar esse problema. Esta solução alternativa é recomendada para DIB geral de processamento.

Código de simulação de maior que 64 K monocromático DIBs SetDIBits() faz com que falhas ou impressões erradas ao utilizar um SetDIBits() , um SetDIBitsToDevice() ou um StretchDIBits() para um driver que não oferece suporte a SetDIBits() .

Copyright 1992 pela Microsoft Corporation. Todos os direitos reservados.

A informação contida neste artigo aplica-se a:
  • Microsoft Windows Software Development Kit 3.1
Palavras-chave: 
kbmt kbdownload kbdownload kb16bitonly kbfile kbinfo kbsample KB81498 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine Translation ou MT), não tendo sido portanto traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 81498  (http://support.microsoft.com/kb/81498/en-us/ )
Retired KB ArticleAviso de Isenção de Responsabilidade sobre Conteúdo do KB Aposentado
Este artigo trata de produtos para os quais a Microsoft não mais oferece suporte. Por esta razão, este artigo é oferecido "como está" e não será mais atualizado.