Comment enregistrer un fichier .gif avec une nouvelle table de couleurs à l'aide de GDI +

Traductions disponibles Traductions disponibles
Numéro d'article: 315780 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

Pour une Visual c# .NET version de cet article, reportez-vous 319061.
Pour une Microsoft Visual Basic .NET version de cet article, reportez-vous 319591.
Le CompuServe GIF Graphics Interchange Format () est conçu avec un maximum de 256 couleurs sont organisées dans une table des couleurs. Pour apporter des modifications courantes à un fichier d'image .gif, vous devez modifier une table de couleurs personnalisé. Toutefois, lorsque GDI + modifie un objet image est alors invité à enregistrer l'image avec l'encodeur GIF, le fichier .gif résultant contient une table des couleurs en demi-teinte.

Pour enregistrer une image avec une table de couleurs personnalisé à l'aide du codeur GIF, vous devez travailler avec une copie de 256 couleurs de l' image GDI + n'a pas modifié.

Plus d'informations

Le fichier image .gif peut exprimer un maximum de 256 couleurs. Couleur est une ressource rare dans le fichier .gif, optimisation de ces couleurs étant une tâche couramment demandée. Pour affecter une table des couleurs optimisée, vous devez pouvoir définir une table arbitraire couleur personnalisée dans un fichier .gif.

Une fois que GDI + modifie une image et puis écrit une image dans un fichier à l'aide du codeur GIF, GDI + écrit le fichier en utilisant une palette de demi-teintes pour qui bits l'objet image ont été couleur réduit. GDI + effectue une conversion de couleur de 32 bits par pixel (32 BPP) lorsqu'il écrit l'image dans le fichier étant donné que toutes les modifications à l'image sont effectuées avec le moteur graphique 32 bits par PIXEL GDI +.

Bien que GDI + prend en charge la création d'images et images de différents formats de pixel et peut donc charger une image .gif, l'utilisation du moteur graphique 32 bits par PIXEL nécessite la conversion 32 BPP lorsque qu'ils sont modifiés par GDI +. Toutefois, une image ou image qui est pas modifié par GDI + conserve son format de pixel d'origine et peuvent être écrites dans un fichier en utilisant la méthode Enregistrer avec le codeur approprié. Cette propriété constitue la base d'une technique que peut enregistrer une image dans un fichier .gif avec une table de couleurs personnalisé.

Vous pouvez écrire une image non modifiée avec l'encodeur GIF et conserver la table des couleurs bitmap intacts ; par conséquent, vous pouvez utiliser cette méthode pour enregistrer un fichier .gif avec une nouvelle table de couleurs.

La méthode consiste à copier les données de l'image à partir d'un objet image d'origine à un objet bitmap temporaire. Cette image temporaire est créé comme un 8 bits par PIXEL indexé bitmap , qui est le format de pixel est utilisé pour enregistrer un fichier .gif. La table des couleurs bitmap est définie à l'aide de la méthode SetPalette et puis la définition d'image est copiée dans le bitmap temporaire. Après avoir créé le bitmap temporaire avec une définition en double, vous pouvez utiliser la méthode Save pour enregistrer avec le codeur GIF, qui conserve la table des couleurs 8 bits par PIXEL.

Pour écrire une image .gif dans un fichier avec une table de couleurs personnalisé, procédez comme suit :
  1. Créer un objet bitmap en double qui est la même taille que la source de l'image .
  2. Définissez la table couleur personnalisée de l'objet bitmap à la table couleur souhaitée.
  3. Utilisez la méthode LockBits pour accéder en écriture aux bits d'image de la copie.
  4. Créer une définition d'image dans la copie en écrivant des index de couleur à la mémoire qui est obtenue à partir de LockBits qui dupliquent les pixels dans l' image d'origine.
  5. Utilisez UnLockBits pour libérer les bits d'image.
  6. Utiliser la copie bitmap avec la table couleur personnalisée pour enregistrer l' image sur un fichier en utilisant les Enregistrer et le codeur GIF.
  7. Libérer la copie d'image de l' image .

Utilisation de l'exemple de code

L'exemple de code dans cet article montre comment utiliser Bitmap.Save pour écrire un fichier .gif avec un tableau de couleurs personnalisé de taille arbitraire. Le code n'est pas optimisé pour performances, car son but est de démonstration uniquement. Les opportunités de meilleures à des fins d'optimisation sont dans le pixel traitement des boucles. GetPixel est une abstraction pratique du format de pixel, mais il est extrêmement lente. L'exemple de code serait beaucoup plus rapide si LockBits permet d'accéder directement le format de pixel. Pour augmenter la vitesse, n'utilisez pas la méthode GetPixel et l'abstraction de classe de couleur . Pour améliorer les performances, réécrivez la conversion en nuances de gris en utilisant entier mathématiques, plutôt qu'en virgule flottante.

L'exemple de fonction accepte les cinq paramètres suivants :
  • Tout objet GDI + image .
  • Nom de fichier pour le fichier cible.
  • Identificateur de classe (CLSID) de l'encodeur GIF.
  • Le nombre de couleurs pour le fichier .gif.
  • Indicateur qui indique si une couleur transparente est nécessaire.
Pour plus d'informations sur la fonction GDI + GetEncoderClsid et pour télécharger l'exemple de code, consultez la documentation MSDN à l'adresse suivante :

Plate-forme SDK : GDI + - Image::Save (NomFichier, clsidEncoder, encoderParams)
http://msdn.microsoft.com/en-us/library/ms533843.aspx
La fonction premier crée un objet bitmap qui a le format de pixel de PixelFormat8BPPIndexed car c'est l'objet qui est enregistré pour créer le fichier .gif avec nColors , et une palette de couleurs aux couleurs personnalisées est créée. Le fichier .gif Obtient la taille et des entrées spécifiques pour la table des couleurs de ColorPalette l'objet bitmap . L'exemple de code crée une échelle de gris à des fins de démonstration car cet algorithme est facile à étendre sur les différentes tailles de tableau de couleurs.

Pour créer le fichier .gif, vous devez initialiser l'objet image 8 bits par PIXEL avec la définition d'image qui doit être écrite dans le fichier. Dans l'exemple de code, un ensemble centralisé de boucles est utilisé pour couleur convertir l'image entrant essentiellement l'espace de couleurs de TV en noir et blanc.

À des fins de démonstration, les pixels d'image source sont accessibles au moyen de la méthode GetPixel d'un objet bitmap qui est une copie de l'image source. Une copie d'image est effectuée, car la classe image n'implémente pas la méthode GetPixel .

Vous pouvez utiliser autres techniques pour accéder aux pixels, comme l'accès direct aux pixels en utilisant la méthode LockBits ou interop avec Windows GDI DIB Sections . Lorsque vous utilisez la fonction BitBlt pour copier une image bitmap à partir d'un HDC GDI + dans un contrôleur de domaine de mémoire GDI DIB section, les fonctions GBitBlt utilise les capacités couleur correspondante de GDI.

Après avoir créé la copie d'image , utilisez la méthode Save avec le CLSID GIF fourni pour écrire la bitmap dans le fichier cible.

Fichiers GIF avec inférieur À 256 couleurs

Le codec GIF dans GDI + version 1.0 code uniquement GDI + images qui sont de 8 BPP. Tous les autres formats d'image sont converties avant le codage. Ce code utilise le format de bitmap de 8 bits par PIXEL pour écrire des fichiers .gif qui ont moins de 256 couleurs car le codec GIF reconnaît les objets de bitmap de 8 bits par PIXEL qui contiennent moins de 256 couleurs par la propriété ColorPalette.Count .

Pour plus d'informations sur les formats de pixel GIF codec, consultez la section "References" de cet article.

Le code de la boucle de traitement qui copie les définitions de pixel de l'image pour les 8 bits par PIXEL bitmap prend en compte la taille de la palette lorsque le code calcule la valeur d'index d'un pixel. Le codec GIF limite la taille de la palette et restreint la définition d'image valeurs index qui sont compatibles avec la taille de palette (c'est-à-dire, la potentielle GIF couleur table) et pouvez donc créer des fichiers .gif avec moins de 256 couleurs.

GIF transparent

Dans l'exemple de code, la routine de création ColorPalette définit que la première entrée de la couleur transparente GIF afin d'illustrer l'utilisation de la fonctionnalité de transparence. Pour cela, le code définissant le composant alpha de l'entrée de couleur sur ZERO. L'exemple de code dans cet article est uniquement pour la démonstration, par conséquent, la couleur de transparence est un choix arbitraire et peut avoir des résultats inattendus dépendent entièrement de la source de l'image .

Le codeur GIF identifie la première couleur en ColorPalette a une valeur alpha de ZERO comme couleur transparente. Cela signifie que la couleur transparente n'a pas à la première entrée dans ColorPalette . Il peut être l'une des 256 couleurs possibles dans la palette, à condition que toutes les entrées précédente contiennent des composants alpha avec des valeurs non nulles. Toutes les entrées ultérieures avec valeurs de composant alpha de ZERO sont ignorées. Toutes les entrées des composants alpha non nulle sont considérés comme opaques.

Remarque : lorsque vous utilisez ce code pour remplacer un fichier existant, vous pouvez voir un problème avec la taille du fichier obtenu. Cela se produit en raison d'un bogue dans GDI + version 1.0 ne tronque pas le fichier.

Pour plus d'informations sur la taille des fichiers image, consultez la section "References" de cet article. Bien que l'article référencé il présente l'utilisation de la classe bitmap dans l'espace de noms System.Drawing du .NET Framework, la rubrique s'applique à GDI + car System.Drawing est implémenté par GDI +.

La licence problème GIF/elle

Microsoft a obtenu une licence de Unisys pour utiliser le format de fichier .gif et autres technologies LZW qui sont couverts par les États-Unis appartenant Unisys et étrangères brevets dans un nombre de produits Microsoft. Toutefois, cette licence n'étend pas aux développeurs tiers qui utilisent des produits de développement de Microsoft ou de trousses à outils pour développer des applications. Tant que développeur tiers, vous devez déterminer si vous devez obtenir une licence de Unisys pour utiliser le format GIF ou les technologies d'elle.

Pour plus d'informations sur les licences d'elle et GIF, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
193543INFO : Unisys GIF et informations de licence LZW Technology

Exemple de code

Status SaveGIFWithNewColorTable(
  Image *pImage,
  const WCHAR* filename,
  const CLSID* clsidEncoder,
  DWORD nColors,
  BOOL fTransparent
)
{
    Status stat = GenericError;

    // GIF codec supports 256 colors maximum.
    if (nColors > 256)
        nColors = 256;
    if (nColors < 2)
        nColors = 2;

    // Make a new 8-BPP pixel indexed bitmap that is the same size as the source image.
    DWORD   dwWidth = pImage->GetWidth();
    DWORD   dwHeight = pImage->GetHeight();

    // Always use PixelFormat8BPPIndexed, because that is the color table
    // based interface to the GIF codec.
    Bitmap  bitmap(dwWidth, dwHeight, PixelFormat8BppIndexed); 

    stat = bitmap.GetLastStatus();

    if (stat != Ok)
        return stat;        // No point in continuing.

    // Allocate the new color table.
    DWORD   dwSizeColorPalette;
    dwSizeColorPalette = sizeof(ColorPalette);      // Size of core structure.
    dwSizeColorPalette += sizeof(ARGB)*(nColors-1);   // The other entries.

    // Allocate some raw space to back the ColorPalette structure pointer.
    ColorPalette *ppal = (ColorPalette *)new BYTE[dwSizeColorPalette];
    if (ppal == NULL) return OutOfMemory;

    ZeroMemory(ppal, dwSizeColorPalette);

    // Initialize a new color table with entries that are determined by
    // some optimal palette finding algorithm; for demonstration 
    // purposes, just do a grayscale. 
    if (fTransparent)
        ppal->Flags = PaletteFlagsHasAlpha;
    else
        ppal->Flags = 0; 
    ppal->Flags |= PaletteFlagsGrayScale;
    ppal->Count = nColors;
    for (UINT i = 0; i < nColors; i++)
    {
        int Alpha = 0xFF;       // Colors are opaque by default.
        int Intensity = i*0xFF/(nColors-1); // even distribution 

        // The GIF encoder makes the first entry in the palette with a
        // zero alpha the "transparent" color in the GIF.
        // For demonstration purposes, the first one is picked arbitrarily.

        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.
        ppal->Entries[i] = Color::MakeARGB( Alpha, 
                                            Intensity, 
                                            Intensity, 
                                            Intensity );
    }

    // Set the palette into the new Bitmap object.
    bitmap.SetPalette(ppal);


    // 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 of the image that
    // you want to export. Otherwise, you might try to interpret the native 
    // pixel format of the image by using a LockBits call.
    // Use PixelFormat32BppARGB so that you can wrap a Graphics around it.
    Bitmap BmpCopy(dwWidth, dwHeight, PixelFormat32BppARGB); 
    stat = BmpCopy.GetLastStatus();
    if (stat == Ok)
    {
        Graphics g(&BmpCopy);

        // Transfer the Image to the Bitmap.
        stat = g.DrawImage(pImage, 0, 0, dwWidth, dwHeight);

        // g goes out of scope here and cleans up.
    }

    if (stat != Ok)
    {
        delete [] (LPBYTE) ppal;
        ppal = NULL;
        return stat;
    }

    // Lock the whole of the bitmap for writing.
    BitmapData  bitmapData;
    Rect        rect(0, 0, dwWidth, dwHeight);

    stat = bitmap.LockBits(
      &rect,
      ImageLockModeWrite,
      PixelFormat8BppIndexed,
      &bitmapData);

    if (stat == Ok)
    {
        // Write to the temporary buffer 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.
        BYTE *pixels;
        if (bitmapData.Stride > 0)
            pixels = (BYTE*) bitmapData.Scan0;
        else
            // If the Stride is negative, Scan0 points to the last             // scanline in the buffer.
            // To normalize the loop, obtain the start of the buffer,
            // which is located (Height-1) scanlines previous.
            pixels = (BYTE*) bitmapData.Scan0 + bitmapData.Stride*(dwHeight-1);
        UINT stride = abs(bitmapData.Stride);

        // Top-down and bottom-up is not relevant to this algorithm.

        for(UINT row = 0; row < dwHeight; ++row)
        {
          for(UINT col = 0; col < dwWidth; ++col)
          {
              // Map palette indexes for a grayscale.
              // If you use some other technique to color convert,
              // put your favorite color reduction algorithm here.
              Color     pixel;
              UINT      i8BppPixel = row * stride + col;

              BmpCopy.GetPixel(col, row, &pixel);

              // Use luminance/chrominance conversion to get grayscale.
              // Basically, turn the image into black and white TV: YCrCb.
              // You do not have to to calculate Cr or Cb because you 
              // throw away 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.GetRed() * 0.299) +
                                (pixel.GetGreen() * 0.587) +
                                (pixel.GetBlue() * 0.114);

              // Gray scale is an intensity map from black to white.
              // Compute the index to the gray scale entry that  
              // approximates the luminance, and then round the index.      
              // Also, constrain the index choices by the number of colors to do
              pixels[i8BppPixel] = (BYTE)(luminance * (nColors-1)/255 +0.5);
          }
        }
    // To commit the changes, unlock the portion of the bitmap.  
        stat = bitmap.UnlockBits(&bitmapData);
    }

    // If destination work was successful, see whether the source was successful.
    if (stat == Ok) stat = BmpCopy.GetLastStatus();

    // See whether the code has been successful to this point.
    if (stat == Ok)
    {
    // Write it out to the disk.
        stat =  bitmap.Save(filename, clsidEncoder, NULL);
    }

    // Clean up after yourself.
    delete [] (LPBYTE) ppal;
    ppal = NULL;
    // BmpCopy goes away on its own when it falls out of scope.

    return stat;
}
				

À propos des exemples de code

Microsoft fournit des exemples de programmation à des fins d'illustration uniquement, sans garantie expresse ou implicite, y compris, mais sans limitation, toute garantie implicite de qualité marchande et/ou d'adéquation à un usage particulier. Cet article suppose que vous êtes familiarisé avec le langage de programmation présenté et les outils utilisés pour créer et déboguer des procédures. Professionnels du support technique Microsoft peuvent vous expliquer la fonctionnalité d'une procédure particulière, mais ils ne modifieront pas ces exemples afin de fournir des fonctionnalités supplémentaires ou des procédures pour répondre à vos besoins spécifiques de construction.
Si vous avez partiellement la programmation, il convient contacter un partenaire certifié Microsoft ou services de conseil Microsoft. Pour plus d'informations, visitez ces sites Web de Microsoft :

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

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

Pour plus d'informations sur les options de support sont disponibles et sur la façon de contacter Microsoft, consultez le site Microsoft suivant : http://support.microsoft.com/default.aspx?scid=fh;EN-US;CNTACTMS

Références

Pour plus d'informations sur les formats de pixel GIF codec, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
318343Information : Fichiers GIF GDI + sont enregistrés à l'aide du format 8 bits par PIXEL
Pour plus d'informations sur la taille des fichiers image, cliquez sur le numéro ci-dessous pour afficher l'article correspondant dans la base de connaissances Microsoft :
312119PRB : Enregistrer la méthode de classe bitmap ne tronquer non taille du fichier
Bien que l'article est référencé dans cette liaison présente l'utilisation de la classe bitmap dans l'espace de noms System.Drawing du .NET Framework, la rubrique s'applique à GDI + car System.Drawing est implémenté par GDI +.

Glossaire

par PIXEL
bits par pixel - le nombre de bits utilisée pour représenter la valeur de couleur de chaque pixel dans une image numérisée ; décrit la disposition physique de définition de chaque pixel des couleurs dans une image. Formats pixel génériquement référencé et courants incluent 32 BPP 24 BPP, 16 BPP, 8 BPP, BPP 4, 1 par PIXEL.
8 BPP
Le format de pixel d'image est exprimée sous la forme huit bits contenus dans un seul octet. La valeur octets est utilisée en tant qu'index dans une table de couleurs qui contient les définitions de couleur rouge-vert-bleu (RVB) actuelles. Étant donné que l'index est un octet de la taille, la table des couleurs est limitée à 256 couleurs.
GIF
Graphiques Interchange Format : un format de fichier image streamable qui a été créé par CompuServe.
RVB
Rouge, vert et bleu - chaque généralement exprimée sous la forme d'un octet et entraînant un triplet de 3 octets de couleur.

Propriétés

Numéro d'article: 315780 - Dernière mise à jour: lundi 12 février 2007 - Version: 3.5
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft GDI+ 1.0
  • Microsoft Windows XP Professional
  • the operating system: Microsoft Windows XP 64-Bit Edition
Mots-clés : 
kbmt kbdswgdi2003swept kbbitmap kbgdiplus kbhowto KB315780 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 315780
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com