GDI + kullanarak yeni bir renk tablosu ile .gif dosyasını kaydetme

Makale çevirileri Makale çevirileri
Makale numarası: 315780 - Bu makalenin geçerli olduğu ürünleri görün.
Hepsini aç | Hepsini kapa

Bu Sayfada

Özet

Bu makalenin Microsoft Visual C# .NET sürümü için bkz: 319061.
Bu makalenin Microsoft Visual Basic .NET sürümü için bkz: 319591.
CompuServe Graphics Interchange Format (GIF) en fazla 256 renkten bir renk tablosu içinde düzenlenmiş tasarlanmıştır. .Gif resim dosyası genel değişiklikler yapmak için özel bir renk tablosu değiştirmeniz gerekir. Ancak, GDI + bir Resim nesnesi düzenler ve sonra resim GIF encoder ile kaydetmek için sorular, noktalı resim renk tablosu ortaya çıkan .gif dosyası içerir.

GIF Kodlayıcısı kullanarak özel bir renk tablosu ile Resim kaydetmek için GDI + değil değiştirdi görüntü 256 renkli bir kopyası ile çalışmanız gerekir.

Daha fazla bilgi

.Gif resim dosyası en çok 256 renk ifade edebilirsiniz. Renk .gif dosyasında önemli bir kaynak olduğundan, bu renkleri en iyi duruma getirme sık istenen bir görevdir. En iyi duruma getirilmiş renk tablosu etkilemek için .gif dosyası içinde herhangi bir rasgele özel renk tablosu ayarlamak mümkün olmalıdır.

GDI + görüntüyü değiştirir ve sonra resim GIF Kodlayıcısı kullanarak bir dosyaya yazar sonra GDI + dosya Resim nesnenin bit sınırlı renk verilmiş olması yarı ton paleti kullanarak yazar. GDI + Renk dönüşümü gelen 32 bit-piksel başına (32 bpp) mu onu yazdığında görüntü dosyası için GDI + 32 bpp grafik motoru ile görüntünün tüm değişikliklerin yapıldığından.

GDI + görüntüleri ve bitmapleri çeşitli piksel biçimlerine oluşturulmasını destekler ve .gif resim yükleyebilir ve bu nedenle de, bunlar GDI + tarafından değiştirildiğinde 32 bpp grafik Altyapısı kullanılmasını 32 bpp dönüştürme necessitates. Bununla birlikte, Resim veya bit eşlem olan değişiklik tarafından GDI + kendi orijinal piksel biçimi korur ve uygun encoder ile kaydetme yöntemini kullanarak bir dosyaya yazılabilir. Bu özellik, .gif dosyasına özel bir renk tablosu ile bir görüntü kaydedebilirsiniz bir teknik temelini oluşturur.

Değiştirilmemiş bir bit eşlem GIF encoder ile yazma ve Bitmap renk tablosu olduğu gibi bırakmak; Bu nedenle, yeni bir renk tablosu ile .gif dosyasını kaydetmek için bu yöntemi kullanabilirsiniz.

Görüntü verileri özgün Resim nesnenin geçici bir Bitmap nesnesine kopyalamak için kullanılan yöntemdir. Bu geçici bir bit eşlembit eşlem, .gif dosyasını kaydetmek için kullanılan piksel biçimi olan 8 bpp sıralı olarak oluşturulur. SetPalette yöntemini kullanarak Bitmap renk tablosu ayarlayın ve sonra geçici Bitmapgörüntü tanımını kopyalanır. Bit eşlem geçici bir yinelenen tanımı oluşturduktan sonra 8-bpp renk tablosunu koruyan GIF encoder ile kaydetmek için Kaydet yöntemini kullanabilirsiniz.

.Gif resmini bir özel renk tablosu içeren bir dosyayı yazmak için aşağıdaki adımları izleyin:
  1. Yinelenen kaynak görüntüaynı boyutta olan bir Bitmap nesnesi oluşturun.
  2. Bitmap nesnesinin özel bir renk tablosu için istenilen renk tablosunu ayarlayın.
  3. Görüntü bitlerini kopya yazma erişim kazanmak için LockBits yöntemini kullanın.
  4. Yansıma tanımı, orijinal görüntününpikselleri çoğaltan LockBits elde edilen bellek renk dizinleri yazma kopya oluşturun.
  5. Görüntü bitlerini serbest bırakmak için UnLockBits kullanın.
  6. Biteşlem kopyalama ile özel renk tablosunu kaydedin ve GIF encoder kullanarak resmi bir dosyaya kaydetmek için kullanın.
  7. Resimbit eşlem kopyasını serbest bırakın.

Örnek kodu kullanma

Bu makaledeki örnek kod Bitmap.Save rasgele boyutu özel bir renk tablosu ile bir .gif dosyası yazmak için nasıl kullanılacağını gösterir. Kodu yalnızca tanıtım amacı, çünkü performans için optimize değil. En iyi duruma getirme için en iyi fırsatları döngüler işleme piksel olur. GetPixel bir piksel biçimine uygun soyutlamadır, ancak çok yavaş. Örnek kodu LockBits piksel biçimini doğrudan erişmek için kullanılan, daha hızlı olacaktır. Hızını artırmak için GetPixel yöntemini ve renk sınıf soyutlama kullanmayın. Performansı artırmak için gri tonlama dönüştürmesini tamsay? matematik kullanarak yerine kayan nokta yeniden yazın.

Örnek işlevi aşağıdaki beş parametre alır:
  • GDI + görüntü nesnesi.
  • Hedef dosya için dosya adı.
  • GIF kodlayıcı sınıf tanımlayıcısı (CLSID).
  • .Gif dosyası için renk sayısı.
  • Saydam bir renk gerekli olup olmadığını gösteren bayrak.
Örnek kodu karşıdan yüklemek ve GDI + GetEncoderClsid işlevi hakkında daha fazla bilgi için aşağıdaki bağlantıyı da msdn Yardım belgelerine bakın:

Platform sdk: GDI + - Image::Save (filename, clsidEncoder, encoderParams)
http://msdn.microsoft.com/en-us/library/ms533843.aspx
İşlevi önce bir Bitmap nesnesi oluşturur, nColorsile .gif dosyası oluşturmak için kaydedilmiş nesne olduğundan PixelFormat8BPPIndexed piksel biçimi yoktur ve özel renkleri bir renk paleti sonra oluşturulur. .Gif dosya boyutunu ve kendi renk tablosu için belirli girdileri Bitmap nesnesinin ColorPalettealır. Bu algoritma çeşitli renk tablo boyutlarını genişletmek kolay olduğu için örnek kod bir gri ölçekli gösterim amacıyla oluşturur.

.Gif dosyası oluşturmak için 8-bpp Bitmap nesnesini dosyasına yazılıp yazılmayacağını Yansıma tanımı ile başlatmalısınız. Örnek kodda döngüleri merkezi kümesi için kullanılan rengi gelen görüntünün aslında siyah beyaz tv renk uzayına dönüştürmek.

Gösterim amacıyla kaynak görüntü piksellerini bir kopyası kaynak görüntüyü bir Bitmap nesnesinin GetPixel yöntemi erişilir. Biteşlem kopyalama görüntü sınıfının GetPixel yöntemi uygulamadığı için yapılır.

Gibi doğrudan erişim Windows GDI DIB bölümleriile LockBits yöntemini veya birlikte çalışabilirliği kullanarak piksel piksel erişmek için başka teknikler kullanabilirsiniz. Bir bit eşlem bir GDI + hdc GDI DIB bölüm bellek etki alanı denetleyicisine kopyalamak için BitBlt işlevini kullandığınızda, GBitBlt işlevlerini GDI renk eşleştirme yeteneklerini kullanır.

Biteşlem kopyalama oluşturduktan sonra bit eşlem hedef dosyaya yazmak için sağlanan GIF CLSID ile Kaydet yöntemini kullanın.

GIF dosyaları daha az 256 renkli

GDI + sürümü 1.0 GIF codec 8 bpp yalnızca GDI + görüntüleri kodlar. Tüm Resim biçimlerini kodlama önce dönüştürülür. Bu kod bpp 8 bit eşlem biçimi GIF codec bileşeni ColorPalette.Count özelliği tarafından 256'dan daha az renk içeren 8 bpp Bitmap nesneleri tanıdığı için 256 renk .gif dosyaları yazmak için kullanır.

GIF codec bileşeni piksel biçimi hakkında daha fazla bilgi için bkz: "BaşvurularBu makalenin "bölümü.

8-bpp Bitmap görüntünün piksel tanımlarını kopyalar işleme döngü kodu kodu bir pikselin dizin değeri hesaplar, palet boyutu dikkate alır. GIF codec bileşeni paleti boyutunu sınırlar ve resmi tanımına palet boyutu (diğer bir deyişle, potansiyel GIF renk tablosu) ile uyumlu olan ve bu nedenle, .gif dosyaları 256 renk oluşturabilirsiniz dizin değerlerini kısıtlar.

GIF saydamlığı

Örnek kodda, ColorPalette oluşturma yordamına GIF saydam renk saydamlık özelliği kullanımını göstermek için ilk girdi ayarlar. Kod renk girişinin Alpha bileşen SIFIRA ayarlayarak bunu yapar. Bu makaledeki örnek kod yalnızca gösterim amacıyla, bu nedenle, saydamlık rengi rasgele bir seçimdir ve olabilir tamamen kaynağında görüntühizmete bağlı beklenmeyen sonuçlar.

GIF Kodlayıcı bir alfa değeri sıfır olarak saydam rengi olan ColorPalette ilk rengi tanımlar. Bu, ColorPalettedosyasındaki ilk girdi olması saydam rengi yok anlamına gelir. Alfa bileşenleri sıfır olmayan değerler içeren tüm önceki girişleri içeren koşuluyla olası 256 renk paletindeki herhangi biri olabilir. Herhangi bir sonraki girişleri alfa Bileşen değerlerini sıfır ile göz ardı edilir. Sıfır olmayan alfa bileşenlerine sahip tüm girişleri opak olarak kabul edilir.

Not: Varolan dosyanın üzerine yazmak için bu kodu kullandığınızda, sonuçta elde edilen dosya boyutu ile ilgili bir sorun görebilirsiniz. GDI + dosyayı kesmediğine sürüm 1.0 bir hata nedeniyle oluşur.

Görüntü dosya boyutları hakkında daha fazla bilgi için bkz: "BaşvurularBu makalenin "bölümü. Burada başvurulan makaleyi System.Drawing ad boşluğunda Bitmap sınıfı .NET Framework'ün kullanımını ele almasına rağmen System.Drawing GDI + tarafından uygulandığı için konu GDI + için geçerlidir.

GIF/lzw lisans sorunu

Microsoft Lisans Unisys .gif dosya biçimi ve Unisys ait ABD ve yabancı patent çeşitli Microsoft ürünleri tarafından kapsanan diğer lzw teknolojileri kullanmak üzere alınan. Ancak, bu lisans, uygulamalar geliştirmek için Microsoft geliştirme ürün veya yazanlar kullanan üçüncü taraf geliştiricilere genişletmiyor. Üçüncü taraf geliştirici olarak, GIF formatı veya lzw teknolojileri kullanmak için Unisys lisans alması gerekiyor olup olmadığını belirlemeniz gerekir.

GIF ve lzw lisansları hakkında ek bilgi için Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
193543 BİLGİ: GIF Unisys ve lzw teknolojisi lisans bilgileri

Örnek kod

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

Örnek kodu hakkında

Microsoft dahil ancak bunlarla sınırlı olmamak üzere, ticari olarak satılabilirlik ve/veya belirli bir amaca uygunluk zımni garantileri veya açık garanti programlama örneklerini yalnızca gösterim amacıyla sağlar; Bu makale, gösterilen programlama dilini ve oluşturmak ve yordamlar hata ayıklamak amacıyla kullanılan araçları kullanmayı bildiğinizi varsayar. Microsoft destek uzmanları belirli bir yordamın işlevselliğinin açıklanmasına yardımcı olabilir, ancak işlevsellik sağlamak veya özel gereksinimlerinizi karşılamak için bir yordam oluşturmak için bu örnekleri değiştirmeyecektir.
Programlama deneyiminiz kısıtlıysa, bir Microsoft Sertifikalı ortağı veya Microsoft Danışmanlık Hizmetleri istiyor. Daha fazla bilgi için aşağıdaki Microsoft Web sitelerini ziyaret edin:

Microsoft Sertifikalı İş ortakları- https://Partner.microsoft.com/Global/30000104

Microsoft Danışmanlık Hizmetleri- http://support.microsoft.com/gp/advisoryservice

Kullanılabilir destek seçenekleri ve Microsoft'a başvurma hakkında daha fazla bilgi için aşağıdaki Microsoft Web sitesini ziyaret edin:http://support.microsoft.com/default.aspx?scid=fh;EN-US;CNTACTMS

Referanslar

GIF codec bileşeni piksel biçimleri hakkında ek bilgi için Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
318343 BİLGİ: GDI + GIF dosyaları 8 bpp biçimi kullanılarak kaydedilir
Görüntü dosya boyutları hakkında ek bilgi için Microsoft Bilgi Bankası'ndaki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
312119 prb: Save yöntemi Bitmap sınıfı, dosya boyutunu kesmediğine
Bu bağlantıyı başvurulan makaleyi System.Drawing ad boşluğunda Bitmap sınıfı .NET Framework'ün kullanımını ele almasına rağmen System.Drawing GDI + tarafından uygulandığı için konu GDI + için geçerlidir.

Terimler sözlüğü

BPP
bit / piksel - sayısallaştırılmış görüntüdeki her pikselin renk değeri göstermek için kullanılan bit sayısı; bir görüntüdeki her pikselin renk tanımı fiziksel yerleşimini tanımlar. 32 bpp, 24 bpp, 16 bpp, 8 bpp, 4 bpp, 1 bpp ortak ve genel olarak başvurulan piksel biçimleri içerir.
8 BPP
Tek baytlık içinde bulunan sekiz bit olarak ifade edilen görüntü piksel biçimi. Bayt değerini gerçek kırmızı-yeşil-mavi (rgb) renk tanımlarını içeren bir renk tablosu indeks olarak kullanılır. Dizin boyutu bayt olduğundan, renk tablosu 256 renkle sınırlı.
GIF
Grafik Değişim Biçimi - CompuServe tarafından oluşturulmuş bir akışlı resim dosyası biçimi.
RGB
Kırmızı, yeşil ve mavi - genellikle her bir bayt ifade ve renk 3 baytlı Üçlü içinde kaynaklanan.

Özellikler

Makale numarası: 315780 - Last Review: 3 Aralık 2012 Pazartesi - Gözden geçirme: 5.0
Bu makaledeki bilginin uygulandığı durum:
  • Microsoft Windows XP Professional Edition
Anahtar Kelimeler: 
kbdswgdi2003swept kbbitmap kbgdiplus kbhowto kbmt KB315780 KbMttr
Machine-translated Article
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir: 315780

Geri Bildirim Ver

 

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