Como salvar um arquivo .gif com uma nova tabela de cores usando translation from VPE for Csharp Visual

O suporte para o Windows XP terminou

A Microsoft terminou o suporte para o Windows XP em 8 de abril de 2014. Esta alteração afetou as suas atualizações de software e opções de segurança. Saiba o que isto significa para você e como permanecer protegido.

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: 319061


Para obter uma versão Microsoft Visual Basic .NET neste artigo, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
319591Como salvar um arquivo .gif com uma nova tabela de cores usando o Visual Basic .NET
Este artigo faz referência o seguinte .NET Framework Class Library namespaces:
  • System.Drawing

NESTA TAREFA

Sumário
GIF (CompuServe Graphics Interchange Format) destina-se com um máximo de 256 cores que são organizados em uma tabela de cores. Para fazer modificações comuns para um arquivo de imagem .gif, você deve alterar uma tabela de cores personalizado. No entanto, quando System.Drawing edita um objeto de imagem e, em seguida, é solicitado a salvar a imagem com o codificador GIF, o arquivo .gif resultante contém uma tabela de cores de meio-tom.

Para salvar uma imagem com uma tabela de cores personalizado usando o codificador GIF, você deve trabalhar com uma cópia de 256 cores de imagem que não tenha modificado System.Drawing .

Noções básicas sobre arquivos .gif que são gravados por System.Drawing e GDI +

O arquivo de imagem .gif pode expressar um máximo de 256 cores. Como cor é um recurso escasso no arquivo .gif, otimizar essas cores é uma tarefa comumente solicitada. Para afetar uma tabela de cores otimizado, você deve ser capaz de definir qualquer tabela arbitrário cor personalizada em um arquivo .gif.

O namespace System.Drawing é principalmente um invólucro GDI +, se, portanto, este artigo refere ao espaço para nome como o GDI +, a menos que comportamento é específico para o namespace System.Drawing é discutido, sendo que, neste caso, o termo System.Drawing é usado.

Depois de GDI + modifica uma imagem e, em seguida, grava uma imagem em um arquivo usando o codificador GIF, GDI + grava o arquivo usando uma paleta de meio-tom para a qual bits do objeto Image foram cor reduzido. GDI + faz uma conversão de cores de 32 bits por pixel (32 BPP) quando ele grava a imagem para o arquivo todas as modificações para a imagem que são feitas com GDI + 32 BPP mecanismo de elementos gráficos.

Embora GDI + oferece suporte à criação de imagens e Bitmaps de vários formatos de pixel e, portanto, pode carregar uma imagem .gif, o uso do mecanismo de elementos gráficos 32 BPP necessita a conversão para 32 BPP quando eles forem modificados pelo GDI +. No entanto, uma imagem ou um bitmap que é não modificado pelo GDI + mantém seu formato de pixel original e podem ser gravados em um arquivo usando o método Save com o codificador apropriado. Essa propriedade constitui a base para uma técnica que pode salvar uma imagem em um arquivo .gif com uma tabela de cores personalizado.

back to the top

Gravar um arquivo .gif arquivo com uma tabela de cores personalizado

Você pode escrever um bitmap e não modificada com o codificador GIF e manter a tabela de cores do bitmap intactos; portanto, você pode usar esse método para salvar um arquivo .gif com uma nova tabela de cores.

O método é copiar os dados da imagem de um objeto de imagem original para um objeto bitmap temporário. Esse bitmap temporário é criado como um 8-BPP indexado bitmap , que é o formato de pixel que é usado para salvar um arquivo .gif. A tabela de cores do bitmap é definida usando o método SetPalette e, em seguida, a definição de imagem é copiada para o bitmap temporário. Depois de criar o bitmap temporário com uma definição duplicada, você pode usar o método Save() para salvá-lo com o codificador GIF, que preserva a tabela de cores 8 BPP.

Para gravar uma imagem .gif em um arquivo com uma tabela de cores personalizado, execute estas etapas:
  1. Crie um objeto bitmap duplicado que é o mesmo tamanho que a fonte de imagem .
  2. Defina a tabela cor personalizada do objeto bitmap para a tabela de cores desejado.
  3. Use o método LockBits para obter acesso de gravação para os bits da imagem da cópia.
  4. Crie uma definição de imagem na cópia, escrevendo índices de cor para a memória que é obtida de LockBits que duplicar os pixels da imagem original.
  5. Use UnLockBits para liberar os bits da imagem.
  6. Use a cópia bitmap com a tabela de cores personalizado para salvar a imagem em um arquivo usando o codificador GIF e Salvar .
  7. Solte a cópia de imagem bitmap .
back to the top

Usando o código de exemplo

O código de exemplo neste artigo demonstra como usar Bitmap.Save para gravar um arquivo .gif com uma tabela de cores personalizado de tamanho arbitrário. O código não está otimizado para desempenho porque sua finalidade é para demonstração somente. As melhores oportunidades de otimização estão em pixel processamento loops. GetPixel é uma abstração conveniente do formato de pixel, mas é bastante lenta. O código de exemplo seria muito mais rápido se você usou LockBits para acessar diretamente o formato de pixel. Para aumentar a velocidade, não use o método GetPixel e a abstração da classe de cor . Para melhorar o desempenho, reescreva a conversão de escala de cinza usando matemática inteiro, em vez de ponto flutuante.

A função de exemplo utiliza os quatro parâmetros a seguir:
  • Qualquer objeto GDI + imagem .
  • O nome de arquivo para o arquivo de destino.
  • O número de cores para o arquivo GIF.
  • Um sinalizador que indica se uma cor transparente é necessária.
A função primeiro cria um objeto bitmap que possui o formato de pixel de PixelFormat.Format8BPPIndexed porque esse é o objeto que é salvo para criar o arquivo .gif com nColors . Em seguida, é criada uma paleta de cores com cores personalizadas. O arquivo .gif obtém o tamanho e a entradas específicas para sua tabela de cores a partir ColorPalette do objeto bitmap . O código de exemplo cria uma escala de cinza para fins de demonstração porque esse algoritmo é fácil de estender por vários tamanhos de tabela de cores.

Para criar o arquivo .gif, você deve inicializar o objeto de bitmap BPP 8 com a definição de imagem que deve ser gravado no arquivo. No código de exemplo, um conjunto central de loops é usado para cor converter a imagem entrada essencialmente o espaço em preto-e-branco de cores TV.

Para fins de demonstração, os pixels de imagem de origem são acessados por meio do método GetPixel() de um objeto bitmap que é uma cópia da imagem de origem. Uma cópia de bitmap é feita porque a classe Image não implementa o método GetPixel() .

Você pode usar outras técnicas para acessar os pixels, como acesso direto aos pixels usando o método LockBits() ou a interoperabilidade com código nativo não gerenciado Windows GDI DIB seções . Quando você usar a função BitBlt para copiar um bitmap de um HDC GDI + para uma seção de DIB GDI controlador de domínio de memória, GBitBlt funções usa a cor de correspondência de capacidade de GDI.

Depois de criar a cópia de bitmap , use o método Save com o objeto ImageFormat.Gif para gravar o bitmap no arquivo de destino.

back to the top

Arquivos GIF com menos de 256 cores

O codec GIF no GDI + versão 1.0 codifica somente GDI + imagens que são BPP 8. Todos os outros formatos de imagem são convertidos antes de codificação. Esse código use o formato de bitmap BPP 8 para gravar arquivos .gif que têm menos de 256 cores porque o codec GIF reconhece 8 BPP bitmap objetos que contêm menos de 256 cores, a propriedade Palette.Count .

Para obter mais informações sobre o codec GIF, consulte a seção "References" deste artigo.

Infelizmente, a classe ColorPalette do namespace System.Drawing do .NET Framework não pode ser instanciada independente de um objeto bitmap . Isso é uma restrição somente a classe System.Drawing.bitmap impõe no .NET Framework; no entanto, para usar a abordagem neste artigo, o objeto bitmap deve ter um novo objeto ColorPalette que contém cores menos que o padrão de 256 ColorPalette .

Para conseguir isso, o código de exemplo define uma função chamada GetColorPalette . Esta função cria um objeto bitmap temporário que tiver uma intensidade de cores próximo ao número de cores solicitado. A função, em seguida, faz referência a propriedade Palette e o retorna ao chamador. Isso cria um novo ColorPalette com um dos vários contagens de cores possíveis: 256 cores, 16 cores ou duas cores (monocromático). Embora você possa criar tabelas de cores em arquivos .gif que forem menores do que 256 cores, cor tabelas estão limitadas a tamanhos que são uma potência de dois.

Quando você limitar tamanhos de tabela de cores a uma potência de dois, você minimiza o espaço desperdiçado. A tabela de cores resultante neste exemplo é 8 cores (2 x 2 x 2). Com o código de exemplo, o arquivo .gif deve ser criado com uma tabela de cores de 16 cores, porque esse é o menor PixelFormat para um bitmap que acomoda seis cores.

O código no loop processamento que copia as definições de pixel da imagem para o bitmap de 8 BPP leva em consideração o tamanho da paleta de quando o código calcula o valor de índice do pixel. O codec GIF limita o tamanho da paleta e restringe a imagem da definição do índice valores que são compatíveis com o tamanho de paleta (ou seja, o potencial GIF cor tabela) e, portanto, pode criar arquivos .gif com menos de 256 cores.

back to the top

GIF transparência

No código de exemplo, a rotina de criação ColorPalette define a primeira entrada como a cor transparente GIF para demonstrar o uso do recurso de transparência. O código faz isso definindo o componente Alpha da entrada de cor como ZERO. O código de exemplo neste artigo é somente para fins de demonstração, portanto, a cor da transparência é uma opção arbitrária e pode ter resultados inesperados que dependem totalmente na fonte de imagem .

O codificador GIF identifica a primeira cor no ColorPalette que possui um valor de alfa de ZERO como cor transparente. Isso significa que a cor transparente não ter que ser a primeira entrada ColorPalette . Ele pode ser qualquer das 256 cores possíveis na paleta, no condition de todas as entradas de anterior contêm componentes Alpha com valores de zero. Todas as entradas posteriores com Alpha componente valores ZERO são ignoradas. Todas as entradas que têm de zero Alpha componentes são consideradas opacas.

back to the top

GIF/LZW questões de licenciamento

Microsoft obteve uma licença de Unisys para usar o formato de arquivo .gif e outras tecnologias LZW que são abordadas pela propriedade Unisys e patentes estrangeiras em um número de produtos da Microsoft. No entanto, essa licença não se estende para desenvolvedores de terceiros que usam produtos de desenvolvimento da Microsoft ou Kits de ferramentas para desenvolver aplicativos. Como um desenvolvedor de terceiros, você precisa determinar se você deve obter uma licença de Unisys para usar o formato .gif ou tecnologias LZW.

Para obter informações adicionais sobre licenças LZW e GIF, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
193543INFO: Unisys GIF e informações de licença de tecnologia LZW
back to the top

Código de exemplo

protected ColorPalette GetColorPalette( uint nColors ){    // Assume monochrome image.    PixelFormat     bitscolordepth = PixelFormat.Format1bppIndexed;    ColorPalette    palette;    // The Palette we are stealing    Bitmap          bitmap;     // The source of the stolen palette    // Determine number of colors.    if (nColors > 2)        bitscolordepth = PixelFormat.Format4bppIndexed;    if (nColors > 16)        bitscolordepth = PixelFormat.Format8bppIndexed;    // Make a new Bitmap object to get its Palette.    bitmap = new Bitmap( 1, 1, bitscolordepth );    palette = bitmap.Palette;   // Grab the palette        bitmap.Dispose();           // cleanup the source Bitmap    return palette;             // Send the palette back}				
protected void SaveGIFWithNewColorTable(    Image       image,    string      filename,    uint        nColors,    bool        fTransparent    ){    // GIF codec supports 256 colors maximum, monochrome minimum.    if (nColors > 256)        nColors = 256;    if (nColors < 2)        nColors = 2;    // Make a new 8-BPP indexed bitmap that is the same size as the source image.    int   Width = image.Width;    int   Height = image.Height;    // Always use PixelFormat8bppIndexed because that is the color    // table-based interface to the GIF codec.    Bitmap  bitmap = new Bitmap(Width,                             Height,                             PixelFormat.Format8bppIndexed);     // Create a color palette big enough to hold the colors you want.    ColorPalette pal = GetColorPalette(nColors);    // Initialize a new color table with entries that are determined    // by some optimal palette-finding algorithm; for demonstration     // purposes, use a grayscale.    for (uint i = 0; i < nColors; i++)    {        uint Alpha = 0xFF;                      // Colors are opaque.        uint Intensity = i*0xFF/(nColors-1);    // Even distribution.         // The GIF encoder makes the first entry in the palette        // that has a ZERO alpha the transparent color in the GIF.        // Pick the first one arbitrarily, for demonstration purposes.        if ( i == 0 && fTransparent) // Make this color index...            Alpha = 0;          // Transparent            // Create a gray scale for demonstration purposes.        // Otherwise, use your favorite color reduction algorithm        // and an optimum palette for that algorithm generated here.        // For example, a color histogram, or a median cut palette.        pal.Entries[i] = Color.FromArgb( (int)Alpha,                                         (int)Intensity,                                         (int)Intensity,                                         (int)Intensity );    }    // Set the palette into the new Bitmap object.    bitmap.Palette = pal;    // Use GetPixel below to pull out the color data of Image.    // Because GetPixel isn't defined on an Image, make a copy     // in a Bitmap instead. Make a new Bitmap that is the same size as the    // image that you want to export. Or, try to    // interpret the native pixel format of the image by using a LockBits    // call. Use PixelFormat32BppARGB so you can wrap a Graphics      // around it.    Bitmap BmpCopy = new Bitmap(Width,                             Height,                             PixelFormat.Format32bppArgb);     {        Graphics g = Graphics.FromImage(BmpCopy);        g.PageUnit = GraphicsUnit.Pixel;        // Transfer the Image to the Bitmap        g.DrawImage(image, 0, 0, Width, Height);        // g goes out of scope and is marked for garbage collection.        // Force it, just to keep things clean.        g.Dispose();    }    // Lock a rectangular portion of the bitmap for writing.    BitmapData  bitmapData;    Rectangle   rect = new Rectangle(0, 0, Width, Height);    bitmapData = bitmap.LockBits(        rect,        ImageLockMode.WriteOnly,        PixelFormat.Format8bppIndexed);    // Write to the temporary buffer that is provided by LockBits.    // Copy the pixels from the source image in this loop.    // Because you want an index, convert RGB to the appropriate    // palette index here.    IntPtr pixels = bitmapData.Scan0;    unsafe     {         // Get the pointer to the image bits.        // This is the unsafe operation.        byte *  pBits;        if (bitmapData.Stride > 0)            pBits = (byte *)pixels.ToPointer();        else            // If the Stide is negative, Scan0 points to the last             // scanline in the buffer. To normalize the loop, obtain            // a pointer to the front of the buffer that is located             // (Height-1) scanlines previous.            pBits = (byte *)pixels.ToPointer() + bitmapData.Stride*(Height-1);        uint stride = (uint)Math.Abs(bitmapData.Stride);        for ( uint row = 0; row < Height; ++row )        {            for ( uint col = 0; col < Width; ++col )            {                // Map palette indexes for a gray scale.                // If you use some other technique to color convert,                // put your favorite color reduction algorithm here.                Color     pixel;    // The source pixel.                // The destination pixel.                // The pointer to the color index byte of the                // destination; this real pointer causes this                // code to be considered unsafe.                byte *    p8bppPixel = pBits + row*stride + col;                pixel = BmpCopy.GetPixel((int)col, (int)row);                // Use luminance/chrominance conversion to get grayscale.                // Basically, turn the image into black and white TV.                // Do not calculate Cr or Cb because you                 // discard the color anyway.                // Y = Red * 0.299 + Green * 0.587 + Blue * 0.114                // This expression is best as integer math for performance,                // however, because GetPixel listed earlier is the slowest                 // part of this loop, the expression is left as                 // floating point for clarity.                double luminance = (pixel.R *0.299) +                    (pixel.G *0.587) +                    (pixel.B *0.114);                // Gray scale is an intensity map from black to white.                // Compute the index to the grayscale entry that                // approximates the luminance, and then round the index.                // Also, constrain the index choices by the number of                // colors to do, and then set that pixel's index to the                 // byte value.                *p8bppPixel = (byte)(luminance * (nColors-1)/255 +0.5);            } /* end loop for col */         } /* end loop for row */     } /* end unsafe */     // To commit the changes, unlock the portion of the bitmap.      bitmap.UnlockBits(bitmapData);    bitmap.Save(filename, ImageFormat.Gif);    // Bitmap goes out of scope here and is also marked for    // garbage collection.    // Pal is referenced by bitmap and goes away.    // BmpCopy goes out of scope here and is marked for garbage    // collection. Force it, because it is probably quite large.    // The same applies to bitmap.    BmpCopy.Dispose();    bitmap.Dispose();}				

Sobre o código de exemplo

Microsoft fornece exemplos de programação apenas para ilustração, sem garantia expressa ou implícita, incluindo, mas não se limitando às garantias implícitas de comercialização e/ou adequação a uma finalidade específica. Este artigo presume que você esteja familiarizado com a linguagem de programação demonstrada e as ferramentas usadas para criar e depurar procedimentos. Profissionais de suporte da Microsoft podem ajudar a explicar a funcionalidade de um determinado procedimento, mas eles não modificarão esses exemplos para fornecer funcionalidades adicionais ou construir procedimentos para atender às suas necessidades específicas.
Se você não tenha muita experiência de programação, talvez queira em contato com um Microsoft Certified Partner ou Microsoft Advisory Services. Para obter mais informações, visite da Microsoft:

Microsoft Certified Partners - https://partner.microsoft.com/global/30000104

Comunicado de Microsoft Services - http://support.microsoft.com/gp/advisoryservice

Para obter mais informações sobre as opções de suporte estão disponíveis e sobre como entrar em contato com a Microsoft, visite o seguinte site: http://support.microsoft.com/default.aspx?scid=fh;EN-US;CNTACTMSback to the top

Solução de problemas

Quando você usa este código para substituir um arquivo existente, você poderá ver o que parece ser um problema com o tamanho do arquivo resultante. Isso ocorre devido a um erro na versão 1.0, que não truncar o arquivo GDIPlus. Para obter mais informações sobre tamanhos de arquivo de imagem, consulte a seção "References".

O código de exemplo também usa a palavra-chave não seguros . Ele faz isso porque o código que move as definições de pixel da fonte de bitmap para o destino bitmap usa um ponteiro para valores de bytes . Ponteiros reais só podem ser usados no código que está marcado como não seguro e que é compilado com a opção de compilador / unsafe . Qualquer código escrito dessa maneira tem impliciations de segurança. Em particular, como código gerenciado pode ser necessário solicitar permissões e pode falhar executar se ele não é confiável.

back to the top
Referências
Para obter informações adicionais sobre formatos de pixel de codec GIF, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
318343INFO: Arquivos de GIF GDI + são salvas usando o formato de 8-BPP
Para obter informações adicionais sobre tamanhos de arquivo de imagem, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
312119PROBLEMA: Salvar método da classe de bitmap não truncar tamanho do arquivo

Para obter informações adicionais sobre essa técnica usando o Microsoft Visual C++, clique no número abaixo para ler o artigo na Base de dados de Conhecimento da Microsoft:
315780COMO: Salvar uma imagem GIF com uma nova tabela de cores usando GDI +
back to the top

Glossário

BPP
bits por pixel - o número de bits usados para representar o valor de cor de cada pixel em uma imagem digitalizada; descreve o layout físico da definição de cor de cada pixel em uma imagem. Formatos de pixel genericamente referenciado e comuns incluem 32 BPP, 24 BPP, 16 BPP, 8 BPP, BPP 4, 1 BPP.
BPP 8
O formato de pixel de imagem que é expresso como oito bits contidos em um byte. O valor de byte é usado como um índice em uma tabela de cores que contém as definições de cores do reais vermelho-verde-azul (RGB). Porque o índice é um byte de tamanho, a tabela de cores está limitada a 256 cores.
GIF
Elementos gráficos Interchange Format - um formato de arquivo de imagem streamable que foi criado pelo CompuServe.
RGB
Vermelho, verde e azul - cada comumente expresso como um byte e resulta em um triplo de 3 bytes de cor.

back to the top

Aviso: este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 319061 - Última Revisão: 12/11/2006 22:23:35 - Revisão: 4.7

Microsoft .NET Framework Software Development Kit 1.0, Microsoft Visual C# .NET 2002 Standard Edition, Microsoft Visual C# 2005 Express Edition, Microsoft Windows XP Professional, the operating system: Microsoft Windows XP 64-Bit Edition

  • kbmt kbdswgdi2003swept kbhowtomaster KB319061 KbMtpt
Comentários