Jak uložit soubor GIF s novou tabulku barvu pomocí GDI +

Překlady článku Překlady článku
ID článku: 315780 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Souhrn

Microsoft Visual C# .NET verzi tohoto článku naleznete 319061.
Microsoft Visual Basic .NET verzi tohoto článku naleznete 319591.
CompuServe Graphics Interchange Format (GIF) je navržen s maximálně 256 barev, které jsou uspořádány v tabulce barev. K provádění běžných změn souboru obrázku GIF, musíte změnit tabulky vlastní barvu. GDI + Upraví objekt obrázek a potom vyzváni k uložení obrázku s kodéru GIF, výsledný soubor GIF obsahuje tabulku barev polotónování.

Uložit obrázek s tabulkou vlastní barvu pomocí kodéru GIF, musí pracovat s 256 barvami kopii obrázku GDI + není změnil.

Další informace

Soubor obrázku GIF lze vyjádřit maximálně 256 barev. Protože je barva scarce prostředku v souboru GIF, optimalizace tyto barvy je běžně požadovaný úkol. Vliv tabulce optimalizovaná barev, musíte být možné nastavit libovolné tabulky libovolný vlastní barvu v souboru GIF.

Po GDI + upravuje obrázek a poté zapíše obrázku do souboru pomocí kodéru GIF, GDI + zapíše soubor pomocí palety polotónů, do kterého byly objekt Image bitů barvu snížena. GDI + provede převodu barev z 32 bitů za pixel (32 BPP) při jej zapíše obrázku do souboru protože provedeny všechny změny do bitové kopie s modulu grafiky 32 BPP GDI +.

Přestože GDI + podporuje vytváření obrázky a obrázky různých formátů pixel a proto načtení obrázku GIF, vyžaduje použití modulu grafiky 32 BPP převod na 32 BPP změně podle GDI +. Obrázek nebo obrázku, který je však není upravena podle GDI + zachová původní formát pixelu a může být zapsána do souboru pomocí metody Uložit s příslušnou kodéru. Tato vlastnost tvoří základ pro techniku můžete uložit obrázek souboru GIF s tabulkou vlastní barvu.

Zápis neupravená rastr s kodéru GIF a zachovat tabulce rastr barev; tedy uložit soubor GIF s novou tabulku barvu použít tuto metodu.

Metoda je zkopírovat data obrázku z původní objekt Image dočasný objekt Bitmap. Tento dočasný rastr je vytvořen jako 8 BPP indexovány rastr, což je formát pixelu, který slouží k uložení souboru GIF. Pomocí metody SetPalette nastaven tabulce barev obrázku a poté definice obrázek zkopírován do dočasné rastr. Po vytvoření dočasné rastr s duplicitní definice můžete uložit s kodéru GIF, která zachová tabulce BPP 8 barev metoda Uložit.

Obrázek GIF zapisovat do souboru s tabulkou vlastní barvu, postupujte takto:
  1. Vytvořit duplicitní objekt Bitmap, který je stejnou velikost jako zdrojový obrázek.
  2. Nastavit vlastní barvu tabulky objekt Bitmap tabulky požadovanou barvu.
  3. Použijte metodu LockBits přístup zápis k bitů bitové kopie.
  4. Vytvořit definici obrázek v kopii pomocí zápisu indexů barev paměti získané z LockBits duplicitní pixelů v původní obrázek.
  5. Slouží k uvolnění bitů obrázek UnLockBits.
  6. Uložit obrázek do souboru pomocí Uložit a GIF kodér pomocí kopie obrázku s tabulkou vlastní barvu.
  7. Uvolněte kopie rastrovýobrázek.

Pomocí kódu ukázka

Ukázkový kód v tomto článku demonstruje použití Bitmap.Save zapsat soubor .gif s tabulkou vlastní barvu libovolné velikosti. Kód není optimalizována pro výkon, protože jeho účelem je pouze demonstrační. Nejlepší příležitosti optimalizace jsou pixel zpracování smyčky. GetPixel je pohodlný abstraction formát pixelu, ale je remarkably pomalé. Ukázkový kód by mnohem rychlejší LockBits použit přímý přístup ke formát pixelu. Ke zvýšení rychlosti, nepoužívejte metody GetPixel a třídy abstraction Barva. Zvýšit výkon, přepište převodu stupních šedi pomocí matematické celé číslo, nikoli plovoucí bodu.

Ukázková funkce trvá pět následující parametry:
  • Libovolný objekt GDI + Image.
  • Název souboru pro cílový soubor.
  • Identifikátor třídy (CLSID) kodéru GIF.
  • Počet barev pro soubor GIF.
  • Příznak označuje, zda je potřeba průhlednou barvu.
Další informace o funkci GDI + GetEncoderClsid a stáhnout ukázkový kód naleznete v dokumentaci nápovědy MSDN na následující odkaz:

Platformy SDK: GDI + - Image::Save (název_souboru, clsidEncoder, encoderParams)
http://msdn.microsoft.com/en-us/library/ms533843.aspx
Funkce nejprve vytvoří objekt Bitmap, který má formát pixelu PixelFormat8BPPIndexed, protože je objekt, který je uložen s nColors vytvořit soubor GIF a potom vytvořen paletu barev s vlastní barvy. Soubor GIF získá od objekt BitmapColorPalette konkrétní položky pro tabulku její barvu a velikost. Ukázkový kód vytváří stupních šedé pro demonstrační účely, protože tento algoritmus je snadno rozšířit nad různé velikosti tabulky barvu.

Chcete-li vytvořit soubor GIF, musíte inicializovat objekt Bitmap 8 BPP s definicí obrázek, který je zapsán do souboru. V ukázkovém kódu je použito pro centrální sadu smyčky barvu převést příchozí obrázek podstatě černé a bílé místo barev TELEVIZE.

Pro demonstrační účely pixelů zdrojového obrázku jsou dostupné prostřednictvím služby GetPixel metodu objektu rastr je kopie zdrojového obrázku. Protože neimplementuje třídu ImageGetPixel metoda je vytvořena kopie obrázku.

Použijete jiné postupy na přístup pixelů například přímý přístup k pixelů pomocí metody LockBits nebo interop Windows GDI DIB oddíly. Při použití funkce BitBlt rastrový obrázek zkopírovat z HDC GDI + do řadiče domény paměti GDI DIB oddíl používá funkce GBitBlt schopnostmi GDI v odpovídající barvu.

Po vytvoření kopie obrázku pomocí metody Uložit s poskytnutého CLSID GIF zapisovat do cílového souboru rastrového obrázku.

Soubory GIF s méně než 256 barev

Kodek GIF v GDI + verze 1.0 kóduje pouze GDI + obrázky, které jsou 8 BPP. Všechny ostatní formáty obrázků jsou převedeny před kódování. Tento kód používá formát rastr 8 BPP zapisovat soubory GIF mají méně než 256 barev, protože kodek GIF rozpozná 8 BPP rastr objekty, které obsahují méně než 256 barev podle vlastnosti ColorPalette.Count.

Další informace o formátech GIF kodek pixel naleznete v "References" v tomto článku.

Kód smyčka pro zpracování, která zkopíruje na obrázek pixel definice 8 BPP rastr bere v úvahu velikost palety při kód vypočítá hodnotu indexu o jeden pixel. Kodek GIF omezuje velikost palety a omezuje obrázek definice indexu hodnoty, které jsou kompatibilní s velikost palety (tj potenciální GIF barvu tabulka) a můžete tedy vytvořit soubory GIF s méně než 256 barev.

Průhlednost GIF

Rutina vytváření ColorPalette v ukázkový kód nastaví první položka být průhledná barva GIF k předvedení použít funkce průhlednosti. Kód to provede nastavením součást Alpha položka Barva nuly. Ukázkový kód v tomto článku je demonstrační pouze pro účely, průhlednost barvy je proto libovolného voleb a může mít neočekávané výsledky závisí zcela na zdrojový obrázek.

Kodér GIF identifikuje první barvu ColorPalette má hodnotu Alpha nuly jako průhlednou barvu. To znamená, že průhlednou barvu nemá být první položka v ColorPalette. Pod podmínkou, že všechny položky preceeding obsahují součásti alfa s nenulové hodnoty může být jeden z možných 256 barev na paletě. Libovolné pozdější položky s hodnotami součást Alpha nuly jsou ignorovány. Všechny položky, které mají nenulové Alpha součásti jsou považovány za neprůhledný.

Poznámka: Při použití tohoto kódu přepsat existující soubor, může se zobrazit problém s velikostí výsledný soubor. K tomu dochází z důvodu chyby v GDI + verze 1.0 není zkrátit soubor.

Další informace o velikosti souboru obrázku naleznete v "References" v tomto článku. Přestože existuje odkazuje článek popisuje použití třídy rastr v oboru názvů System.Drawing .NET Framework, téma se týká GDI + protože System.Drawing je implementován GDI +.

GIF/LZW Licensing problémů

Microsoft získal licenci z Unisys použít formát souboru GIF a dalších technologií LZW, které jsou kryty vlastněných Unisys USA a zahraniční patenty počet produktů. Tato licence se však nerozšiřuje výrobců vývojáři, kteří používají vývoje produktů nebo toolkits vývoj aplikací. Jako vývojář výrobců musíte určit, zda musí získat licenci z Unisys pomocí formátu GIF nebo LZW technologií.

Další informace o licence LZW a GIF klepněte na článek číslo článku databáze Microsoft Knowledge Base:
193543INFORMACE: LZW Technology licenční informace a Unisys GIF

Ukázkový kód

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

O ukázkový kód

Ukázky programů jsou společností Microsoft poskytovány pouze pro ilustraci bez žádné záruky výslovně uvedené ani předpokládané, včetně předpokládaných záruk vztahujících se k obchodovatelnosti nebo vhodnosti pro určitý účel. Tento článek předpokládá, že uživatel je obeznámen s programovacím jazykem, který je předmětem ukázky, a s nástroji použitými pro vytvoření a ladění skriptu. Pracovníci technické podpory společnosti Microsoft mohou vysvětlit funkce určitého postupu, nemohou však následující příklady rozšířit o další funkce nebo konstrukce podle konkrétních požadavků uživatele.
Pokud máte zkušenosti s programováním omezený, můžete kontaktovat partnera s certifikátem Microsoft nebo služby Advisory. Na další informace těchto webech společnosti Microsoft:

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

Služba Microsoft zpravodaje - http://support.microsoft.com/gp/advisoryservice

Další informace o možnostech podpory, které jsou k dispozici a o možnostech kontaktování společnosti Microsoft na následujícím webu společnosti Microsoft: http://support.microsoft.com/default.aspx?scid=fh;EN-US;CNTACTMS

Odkazy

Další informace o formátech GIF kodek pixel klepněte na článek číslo článku databáze Microsoft Knowledge Base:
318343INFORMACE: Soubory GIF GDI + jsou uložené použití formát 8-BPP
Další informace o velikosti souboru obrázku klepněte na článek číslo článku databáze Microsoft Knowledge Base:
312119PRB: Uložit metodu třídy rastr není zkrátit velikost souboru
Ačkoli se odkazuje tento odkaz popisuje použití třídy rastr v oboru názvů System.Drawing .NET Framework, téma se týká GDI + protože System.Drawing je implementován GDI +.

Slovníček

B/P
bitů na pixel - počet bitů představovat hodnotu barvy každý pixel v digitálních obrázků; popisuje fyzické rozložení každý pixel definici barev v obrázku. Běžné a obecně odkazované pixel formáty patří BPP 32, 24 BPP, BPP 16, 8 BPP, BPP 4, 1 BPP.
8 B/P
Formát pixelu obrázek, který je vyjádřen jako osm bitů obsažených v jeden bajt. Hodnota bajtu slouží jako index do tabulky barvu, která obsahuje skutečné definice barvu červená zelená modrá (RGB). Protože index je jeden bajt velikost, barvu tabulky je omezena na 256 barev.
GIF
Grafický formát - streamable image file format, který byl vytvořen CompuServe.
RGB
Červená, zelená a modrá - každý běžně vyjádřena bajtu a výsledkem triplet barvu bajtu 3.

Vlastnosti

ID článku: 315780 - Poslední aktualizace: 12. února 2007 - Revize: 3.5
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft GDI+ 1.0
  • Microsoft Windows XP Professional
  • the operating system: Microsoft Windows XP 64-Bit Edition
Klíčová slova: 
kbmt kbdswgdi2003swept kbbitmap kbgdiplus kbhowto KB315780 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:315780

Dejte nám zpětnou vazbu

 

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