Zum Speichern von GIF-Datei mit einer neuen Farbe Tabelle mithilfe von GDI +

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 315780 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Alles erweitern | Alles schließen

Auf dieser Seite

Zusammenfassung

Eine Microsoft Visual c# .NET Version dieses Artikels finden Sie unter 319061.
Eine Microsoft Visual Basic .NET Version dieses Artikels finden Sie unter 319591.
CompuServe Graphics Interchange Format (GIF) ist mit einem Maximum von 256 Farben vorgesehen, die in einer Farbtabelle angeordnet sind. Häufige Änderungen an einer GIF-Bilddatei vornehmen, müssen Sie eine benutzerdefinierte Farbe-Tabelle ändern. Wenn GDI + Bildobjekt bearbeitet und dann aufgefordert wird, das Bild mit der GIF-Encoder zu speichern, enthält die resultierende GIF-Datei jedoch eine Halbton-Farbtabelle.

Um ein Bild mit einer benutzerdefinierten Farbe Tabelle mithilfe des Encoders GIF zu speichern, müssen Sie mit einer 256-Farben-Kopie des Bildes arbeiten, die GDI + nicht geändert hat.

Weitere Informationen

Die GIF-Bilddatei kann maximal 256 Farben Ausdrücken. Da Farbe eine knappe Ressource in die GIF-Datei ist, ist das Optimieren der Farben ein häufig angeforderte Vorgang. Um eine optimierte Farbtabelle zu beeinflussen, müssen Sie jede beliebige benutzerdefinierte Farbe-Tabelle in eine GIF-Datei festgelegt sein.

Nachdem GDI + ein Bild ändert und schreibt ein Bild in eine Datei mithilfe des GIF-Encoders, schreibt GDI + die Datei mit eine Halbtonpalette, das Image -Objekt Bits Farbe verkleinert wurden. GDI + wird eine Farbkonvertierung aus 32 Bits pro Pixel (32 BPP) Wenn es schreibt das Bild in die Datei da alle Änderungen auf das Bild mit dem GDI + 32-BPP Grafiken Modul vorgenommen werden.

Obwohl GDI + die Erstellung von Bildern und Bitmaps der verschiedene Pixelformate unterstützt und kann daher ein GIF-Bild laden, muss die Verwendung von 32-BPP-Grafikengine die Konvertierung in 32 BPP, wenn Sie von GDI + geändert werden. Ein Bild oder Bitmap , ist jedoch nicht geändert GDI + behält seine ursprüngliche Pixelformat und können in eine Datei mithilfe der Save -Methode mit den entsprechenden Encoder geschrieben werden. Diese Eigenschaft bildet die Grundlage für eine Technik, die ein Bild GIF-Datei mit einer benutzerdefinierten Farbe-Tabelle speichern können.

Sie können eine unveränderte Bitmap mit der GIF-Encoder schreiben und die Farbtabelle der Bitmap unverändert beibehalten, daher können Sie diese Methode verwenden, um eine GIF-Datei mit einer neuen Farbe-Tabelle zu speichern.

Die Methode besteht darin, die Bilddaten aus einem ursprünglichen Abbild -Objekt in ein temporäres Bitmap -Objekt zu kopieren. Dieser temporäre Bitmap wird erstellt, wie eine 8-BPP indiziert Bitmap , also die Pixel-Format, das zum Speichern einer GIF-Datei verwendet wird. Die Farbtabelle der Bitmap wird mithilfe der SetPalette -Methode festgelegt, und anschließend wird die Bild-Definition zu der temporären Bitmap kopiert. Nach dem Erstellen der temporären Bitmap eine doppelte Definition können Sie der Save -Methode, mit der Encoder GIF zu speichern die beibehält, die 8-BPP-Farbtabelle.

Gehen Sie folgendermaßen vor um ein GIF-Bild in eine Datei mit einer benutzerdefinierten Farbe-Tabelle zu schreiben:
  1. Erstellen Sie ein doppeltes Bitmap -Objekt, das die gleiche Größe wie die Quelle Bild ist.
  2. Legen Sie die benutzerdefinierte Farbtabelle der Bitmap -Objekt die gewünschte Farbe-Tabelle.
  3. Verwenden Sie die LockBits -Methode, um Schreibzugriff auf Bild-Bits der Kopie zuzugreifen.
  4. Erstellen Sie eine Bild-Definition in der Kopie, indem Sie Farbe Indizes auf den Speicher, der von LockBits , die die Pixel in das ursprüngliche Bild duplizieren abgerufen wird schreiben.
  5. Verwenden Sie UnLockBits , um die Bild-Bits freizugeben.
  6. Mit der benutzerdefinierten Farbe-Tabelle mit Hilfe der Bitmap Kopie speichern das Bild in einer Datei mithilfe von Speichern und den GIF-Encoder.
  7. Freigeben der Bitmap Kopie des Bildes .

Verwenden des Beispielcodes

Der Beispielcode in diesem Artikel demonstriert, wie von Bitmap.Save zum Schreiben von GIF-Datei mit einer benutzerdefinierten Farbe Tabelle beliebiger Größe. Der Code ist nicht für die Leistung optimiert, da Demo nur seinen Zweck dient. Die besten Möglichkeiten für Optimierung sind in der Verarbeitung von Schleifen Pixel. GetPixel ist eine bequeme Abstraktion des PixelFormats, aber es außergewöhnlich langsam ist. Der Beispielcode wäre viel schneller, wenn Sie LockBits das Pixelformat direkt zugreifen. Um die Geschwindigkeit zu erhöhen, verwenden Sie nicht die GetPixel -Methode und die Color -Klasse Abstraktion. Um die Leistung zu verbessern, Schreiben Sie Graustufen-Konvertierung Ganzzahl Mathematik verwenden, anstatt Gleitkommazahl.

Die Beispielfunktion verwendet die folgenden fünf Parameter:
  • Ein beliebiges GDI + Bild -Objekt.
  • Der Name der Datei für die Zieldatei.
  • Der Klassenbezeichner (CLSID) des Encoders GIF.
  • Die Anzahl der Farben für die GIF-Datei.
  • Ein Flag, das angibt, ob eine transparente Farbe erforderlich ist.
Weitere Informationen über die GDI +- GetEncoderClsid -Funktion und zum download des Beispielcodes, finden Sie in der MSDN-Hilfe-Dokumentation unter den folgenden Link:

Platform SDK: GDI + - Image::Save (Filename, ClsidEncoder, EncoderParams)
http://msdn.microsoft.com/en-us/library/ms533843.aspx
Die Funktion zuerst erstellt eine Bitmap -Objekt, das Pixelformat der PixelFormat8BPPIndexed hat, da, das Objekt ist, die zum Erstellen der GIF-Datei mit nColors gespeichert ist und dann wird eine Farbpalette mit benutzerdefinierten Farben erstellt. Die GIF-Datei erhält die Größe und bestimmte Einträge für die Farbtabelle von der Bitmap -Objekt ColorPalette . Der Beispielcode erstellt eine graue Wertskala zu Demonstrationszwecken, da Algorithmus leicht über verschiedene Größen von Farbe Tabelle erweitert werden.

Um die GIF-Datei erstellen, müssen Sie BPP 8 Bitmap -Objekt mit der Bild-Definition initialisieren, die in die Datei geschrieben werden. Im Beispielcode, eine zentrale Reihe von Schleifen ist verwendet Farbe eingehende Bild in im Wesentlichen die schwarzen und weißen TV-Farbraum konvertieren.

Zu Demonstrationszwecken werden die Quelle Bildpixel durch mithilfe der GetPixel -Methode ein Bitmap -Objekt zugegriffen, das eine Kopie des Quellbildes. Eine Bitmap -Kopie erfolgt, da die Image -Klasse die GetPixel -Methode nicht implementiert.

Andere Techniken können Sie auf die Pixel, z. B. direkten Zugriff auf die Pixel mithilfe der LockBits -Methode oder Interop mit Windows-GDI-DIB-Abschnitte zugreifen. Wenn Sie die BitBlt -Funktion verwenden, um eine Bitmap von GDI +-HDC zu einem Domänencontroller GDI DIB Abschnitt Speicher zu kopieren, verwendet die GBitBlt -Funktionen die entsprechende Farbe Fähigkeiten von GDI.

Nach dem Erstellen der Bitmap Kopie verwenden Sie die Speichern -Methode mit der bereitgestellten GIF-CLSID, um die Bitmap in die Zieldatei schreiben.

GIF-Dateien mit weniger als 256 Farben

Der GIF-Codec in GDI +, Version 1.0 codiert nur GDI + Abbilder , die 8 BPP sind. Alle anderen Bild -Formate werden vor der Codierung konvertiert. Dieser Code verwendet das BPP 8 Bitmap Format GIF-Dateien schreiben, die weniger als 256 Farben, haben da der GIF-Codec 8 BPP Bitmap Objekte erkennt, die von der ColorPalette.Count -Eigenschaft weniger als 256 Farben enthalten.

Weitere Informationen über GIF-Codec Pixelformate finden Sie unter dem Abschnitt "References" dieses Artikels.

Der Code in die Verarbeitung-Schleife, die das Bild Pixel Definitionen in der BPP 8- Bitmap kopiert berücksichtigt die Größe der Palette Wenn der Code eines Pixels Indexwert berechnet. Der GIF-Codec beschränkt die Größe der Palette und schränkt die Definition des Bildes Indexwerte, die kompatibel mit der Palette-Größe (d. h., der potenzielle GIF Farbe Tabelle), und GIF-Dateien können daher mit weniger als 256 Farben erstellen.

GIF-Transparenz

In der Beispielcode legt die Routine ColorPalette Erstellung den ersten Eintrag die transparente GIF-Farbe um die Verwendung der Transparenz-Feature zu veranschaulichen. Der Code wird dadurch die Alpha-Komponente von den Eintrag Farbe auf Null festlegen. Der Beispielcode in diesem Artikel dient nur zu Demonstrationszwecken und daher die Transparenzfarbe ist eine beliebige Wahl möglicherweise unerwartete Ergebnisse, die vollständig von der Quelle Bild abhängen.

Der GIF-Encoder identifiziert die erste Farbe in der ColorPalette , die einen Alphawert von NULL als transparente Farbe aufweist. Dies bedeutet, dass die transparente Farbe nicht sollen den ersten Eintrag in der ColorPalette . Es kann eine der möglichen 256 Farben in der Palette sein, auf Bedingung, dass alle vorhergehender Einträge Alpha-Komponenten mit Werten ungleich Null enthalten. Alle späteren Einträge mit Werten von Alpha-Komponente von Null werden ignoriert. Alle Einträge, die ungleich 0 (null) Alpha-Komponenten gelten undurchsichtig.

Hinweis : Wenn Sie diesen Code zum Überschreiben einer vorhandenen Datei verwenden, möglicherweise Sie ein Problem mit der Größe der resultierenden Datei angezeigt. Dies tritt aufgrund eines einen Fehler in GDI +, Version 1.0, die die Datei nicht abgeschnitten wird.

Weitere Informationen über Image Dateigrößen finden Sie unter dem Abschnitt "References" dieses Artikels. Obwohl die verwiesen wird, gibt es die Verwendung der Bitmap -Klasse im System.Drawing -Namespace von .NET Framework erläutert, gilt das Thema GDI +, da System.Drawing von GDI + implementiert wird.

Das GIF/LZW-Lizenzen registrieren

Microsoft hat eine Lizenz erhalten, von Unisys verwenden Sie das GIF-Dateiformat und andere LZW-Technologien, die von der Unisys gehören US und fremden Patente in einer Reihe von Microsoft-Produkten enthalten sind. Diese Lizenz wird jedoch nicht auf Entwickler von Drittanbietern ausgeweitet, die Microsoft Development-Produkte oder Toolkits, verwenden um Anwendungen zu entwickeln. Als Entwickler von Drittanbietern müssen Sie bestimmen, ob eine Lizenz von Unisys verwenden Sie das GIF-Format oder der LZW-Technologien zu erhalten.

Weitere Informationen zu LZW-Lizenzen und GIF folgendem Artikel der Microsoft Knowledge Base:
193543INFO: Unisys GIF und LZW Technology-Lizenzinformationen

Beispielcode

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;
}
				

Zum Beispielcode

Microsoft bietet Programmierbeispiele für Abbildung nur ohne Gewährleistung oder konkludent, einschließlich, aber nicht beschränkt auf konkludenten Garantien der Handelsüblichkeit und/oder Eignung für einen bestimmten Zweck. Die zur Verfügung gestellten Makro- und Programmierungsbeispiele sollen lediglich exemplarisch die Funktionsweise des Beispiels aufzeigen. Spezialisten von Microsoft Support Services können bei Erläuterung die Funktionalität einer bestimmten Prozedur helfen, Sie werden ändert jedoch nicht Beispielen bieten Funktionen hinzugefügt oder Verfahren, um Ihren speziellen Anforderungen erstellen.
Wenn Sie Programmiererfahrung, beschränkt haben, sollten Sie ein Microsoft Certified Partner oder die Microsoft Advisory Services wenden. Weitere Informationen finden Sie auf diese Websites von Microsoft:

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

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

Weitere Informationen zu den Supportoptionen, die verfügbar sind und wie Sie Microsoft kontaktieren besuchen Sie in der folgenden Website: http://support.microsoft.com/default.aspx?scid=fh;EN-US;CNTACTMS

Informationsquellen

Weitere Informationen GIF Codec-Pixelformate folgendem Artikel der Microsoft Knowledge Base:
318343INFO: GDI + GIF-Dateien werden mit das BPP 8-Format gespeichert
Weitere Informationen zu Dateigrößen Bild finden folgendem Artikel der Microsoft Knowledge Base:
312119PRB: Save-Methode des Bitmap-Klasse nicht Datei abgeschnitten.
Obwohl der Artikel, auf die in dieser Verknüpfung verwiesen wird die Verwendung der Bitmap -Klasse im System.Drawing -Namespace von .NET Framework behandelt, gilt das Thema GDI +, da System.Drawing von GDI + implementiert wird.

Glossar

BPP
Bits pro Pixel - die Anzahl der Bits zum Darstellen von des Farbwert der einzelnen Pixel in ein digitalisiertes Bild; beschreibt das physische Layout der Farbdefinition jedes Pixel in einem Bild. Allgemeine und Allgemein referenzierten Pixelformaten gehören 32 BPP, 24 BPP, 16 BPP, BPP 8, 4 BPP, BPP 1.
8 BPP
Das Bild Pixelformat, das als acht Bits in einem Byte enthaltenen ausgedrückt wird. Der Bytewert wird als Index in einer Farbtabelle verwendet, die die tatsächlichen Rot-Grün-Blau (RGB) Farbe Definitionen enthält. Da der Index ein Byte groß ist, ist die Farbtabelle auf 256 Farben beschränkt.
GIF
Graphics Interchange Format - eine streamable Bilddateiformat, das von CompuServe erstellt wurde.
RGB
Rot, Grün und Blau - jedes häufig ausgedrückt als ein Byte und eine Farbe 3-Byte-Dreiergruppe führt.

Eigenschaften

Artikel-ID: 315780 - Geändert am: Montag, 12. Februar 2007 - Version: 3.5
Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft GDI+ 1.0
  • Microsoft Windows XP Professional
  • the operating system: Microsoft Windows XP 64-Bit Edition
Keywords: 
kbmt kbdswgdi2003swept kbbitmap kbgdiplus kbhowto KB315780 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 315780
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.

Ihr Feedback an uns

 

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