GDI+ を使用して、新しい色テーブルに .gif ファイルを保存する方法

文書翻訳 文書翻訳
文書番号: 315780
すべて展開する | すべて折りたたむ

目次

概要

マイクロソフト ビジュアルを C#。この資料のバージョンを NET を参照してください。 319061.
マイクロソフトの Visual Basic では。この資料のバージョンを NET を参照してください。 319591.
CompuServe グラフィックス インターチェンジ形式 (GIF)、最大 256 色を色テーブルに配置されますされています。一般的な .gif イメージ ファイルを変更するには、カスタム カラー テーブルを変更する必要があります。ただしと GDI+ を編集します。 イメージ オブジェクトし、GIF エンコーダーでは、画像を保存するよう求められます、ハーフトーン カラー テーブルには結果は、.gif ファイルが含まれます。

保存するのには イメージ GIF エンコーダーを使用して、カスタム カラー テーブルで、256 色のコピーで作業する必要があります、 イメージ その GDI+ は変更されていません。

詳細

.Gif イメージ ファイルは、最大 256 色を表現できます。色は、.gif ファイル内の貴重なリソースのため、それらの色の最適化は一般的に要求される作業です。最適化されたカラー テーブルに影響するには、任意のカスタム カラー テーブルを .gif ファイルに設定できる必要があります。

GDI+ を変更した後、 イメージ [書き込みイメージを GIF エンコーダー GDI+ を使用してファイルに書き込みますファイル ハーフトーンのパレットを使用して、 イメージ オブジェクトのビットは、カラーの削減されています。GDI+ は、色変換から 32 ビット/ピクセル (32 BPP) に書き込む場合、イメージ ファイルに 32 BPP グラフィック エンジン GDI+ のイメージに対するすべての変更が行われるため。

GDI+ の作成をサポートしていますが イメージビットマップ 必要、GDI+ によって変更されるとさまざまなピクセル形式とすることができますのため負荷は 32 BPP グラフィック エンジンの .gif 画像を 32 BPP への変換です。ただし、 イメージ または ビットマップ です。 いない 変更 GDI+ ピクセルの元の形式を保持し、使用してファイルに書き込まれることができます、、 保存 適切なエンコーダーによる方法です。このプロパティでは、保存できる手法を基礎に イメージ .gif ファイルに、カスタム カラー テーブルを使用します。

変更を書き込むことができます。 ビットマップ 保持する、GIF エンコーダーでは、 ビットマップ カラー テーブルはそのままです。したがって、新しい色テーブルに .gif ファイルを保存するのにはこのメソッドを使用できます。

メソッドは、元の画像データをコピーするのには イメージ オブジェクトが一時的に ビットマップ オブジェクトです。この一時的です ビットマップ 8 インデックス BPP として作成されます。 ビットマップ、.gif ファイルの保存に使用されるピクセル形式となります。は、 ビットマップ カラー テーブルを使用することによって設定を SetPalette メソッドを作成] をポイントし、[画像の定義を一時的にコピーします。 ビットマップ.一時を作成した後 ビットマップ 重複する定義を使用できます、 保存 8 BPP カラー テーブルを保持する、GIF エンコーダーで保存します。

ファイルに、カスタム カラー テーブルを .gif 画像を作成するには、次の手順を実行します。
  1. 複製を作成します。 ビットマップ オブジェクトは、ソースと同じサイズです。 イメージ.
  2. ユーザー設定の色の設定は、 ビットマップ 目的のカラー テーブルに含まれる ◇
  3. 使用して、 LockBits イメージのビットのコピーへの書き込みアクセスを取得するメソッドです。
  4. 色のインデックスから得られるメモリに書き込むことにより、イメージ定義内のコピーを作成します。 LockBits 元のピクセルを複製します。 イメージ.
  5. 使用 UnLockBits イメージのビットを解放するには。
  6. 使用して、 ビットマップ カスタム カラー テーブルを保存するには イメージ 使用してファイル 保存 GIF エンコーダーとします。
  7. リリースは、 ビットマップ コピーは、 イメージ.

サンプル コードを使用します。

この資料のサンプル コードを使用する方法を示しています。 Bitmap.Save .gif ファイルを任意のサイズのカスタム カラー テーブルを作成するには。その目的はデモンストレーション用だけですので、コードのパフォーマンスを最適化されていません。最適化の最良のオポチュニティは、ループ処理内のピクセルです。 GetPixel ピクセル形式の便利な抽象化が非常に低速です。サンプル コードを使用すると非常に高速になります LockBits ピクセル形式に直接アクセスするには。速度を上げるには、使用しない、 GetPixel メソッドおよび カラー クラスの抽象化します。パフォーマンスを向上させるには、整数の演算を使用してではなく浮動小数点のグレースケール変換を書き直します。

サンプル関数は、次の 5 つのパラメーターを受け取ります。
  • その GDI+ イメージ オブジェクトです。
  • 対象ファイルのファイル名。
  • GIF エンコーダーのクラス識別子 (CLSID)。
  • 色は、.gif ファイルの数。
  • 透明な色が必要かどうかを示すフラグ。
詳細については、GDI+ GetEncoderClsid 機能およびサンプル コードをダウンロードするのには、MSDN ヘルプには、次のリンクを参照してください。

プラットフォーム SDK: GDI+ ・ Image::Save (ファイル名、clsidEncoder、encoderParams)
http://msdn.microsoft.com/en-us/library/ms533843.aspx
最初に、関数を作成します。 ビットマップ オブジェクトのピクセル形式を持つ PixelFormat8BPPIndexed .gif ファイルを作成するのには、保存されるオブジェクトであるため nColors、および、ユーザー設定の色とカラー パレットが作成されます。.Gif ファイルのサイズとのカラー テーブルの特定のエントリを取得、 ビットマップ オブジェクト ColorPalette.そのアルゴリズムはカラー テーブルのさまざまなサイズに拡張するは簡単であるため、サンプル コードはデモンストレーション用グレースケールを作成します。

.Gif ファイルを作成するには、8 BPP を初期化する必要があります。 ビットマップ イメージ定義をファイルに書き込むオブジェクト。サンプル コードでは、中央の一連のループのために使用されるですカラー黒と白のテレビ カラー スペースには、基本的に受信イメージを変換します。

デモンストレーションのため、ソース イメージのピクセルを使用してアクセスするには、 GetPixel メソッドは、 ビットマップ 元のイメージのコピーであるオブジェクト。A ビットマップ コピーを作成するために イメージ クラスを実装しません、 GetPixel メソッドです。

その他の方法を使用できますを使用して、ピクセルへの直接アクセスなどのピクセルにアクセスするのには LockBits メソッドまたは相互 Windows GDI の DIB セクション.使用すると、 Bitblt 関数 DIB セクションの GDI メモリのドメイン コント ローラーには、Gdi + HDC からビットマップをコピーします、 GBitBlt 関数は、GDI の能力と一致する色を使用します。

作成した後、 ビットマップ コピー、使用、 保存 提供されている GIF CLSID をターゲット ファイルにビットマップを作成する方法です。

少ない 256 色が GIF ファイル

GIF コーデック GDI+ のバージョン 1.0 では GDI+ のみエンコードします。 イメージ 8 BPP です。他のすべての イメージ 形式は、エンコードする前に変換されます。このコードは、8 BPP を使用します。 ビットマップ 8 BPP GIF コーデックを認識するためにより少ない 256 色の .gif ファイルを作成する書式設定します。 ビットマップ によってより少ない 256 色が含まれているオブジェクトは、 ColorPalette.Count [プロパティ] します。

GIF コーデックのピクセル形式の詳細についてを参照してください、"参照"この資料の「。

8 BPP には画像のピクセルの定義をコピーする処理ループ内のコード ビットマップ コードは、ピクセルのインデックス値を計算すると、パレットのサイズを考慮してください。GIF コーデック パレットのサイズを制限してイメージ定義をパレットのサイズ (つまり、潜在的な GIF 色テーブル)、互換性のあるより少ない 256 色の .gif ファイルを作成できますしたがって、インデックスの値に制限されます。

透明 GIF

サンプル コードは、 ColorPalette 透過性機能の使用をデモンストレーションする GIF の透明な色にするのには、最初のエントリの作成ルーチンを設定します。"アルファ"コンポーネントを設定することにより、コードがこの処理を カラー ゼロのエントリです。この資料のサンプル コードはデモンストレーションのみを目的です、したがって、透過色は任意選択ですが、ソースに完全に依存する予期しない結果 イメージ.

GIF エンコーダーで先頭のカラーを識別する、 ColorPalette アルファ値が 0 に設定、透明な色があります。これは、透明色の最初のエントリにしていないことを意味、 ColorPalette.アルファ コンポーネントが 0 以外の値を持つの後ろのすべてのエントリが含まれていれば、それは、256 色のパレットでは、いずれかです。ゼロのアルファ コンポーネントの値を後でエントリは無視されます。アルファ コンポーネントをゼロ以外の値を持つすべてのエントリは、不透明と見なされます。

メモ: 既存のファイルを上書きするのにはこのコードを使用すると、問題が、結果として得られるファイルのサイズを参照してください可能性があります。これで GDI+ ファイルを切り捨てることはありませんバージョン 1.0 のバグのため発生します。

イメージ ファイルのサイズの詳細についてを参照してください、"参照"この資料の「。参照されている資料の使用をについて説明しますが、 ビットマップ クラスのでは System.Drawing 名前空間の。NET Framework」GDI+ するため適用されます。 System.Drawing GDI+ によって実装されます。

GIF または LZW ライセンスの問題

マイクロソフトは、.gif ファイル形式および Unisys が所有する米国およびさまざまなマイクロソフト製品での外部の特許でカバーされている他の LZW テクノロジを使用する Unisys からのライセンスを取得します。ただし、本契約はマイクロソフトの開発製品またはツールキットを使用してアプリケーションを開発するサード パーティの開発者に拡張されません。サード パーティの開発者は、GIF 形式または LZW テクノロジを使用する Unisys からライセンスを取得する必要があるかどうかを確認する必要があります。

LZW ライセンスおよび GIF の詳細については、「サポート技術情報」資料を参照するには、次の文書番号をクリックしてください。
193543 情報: Unisys が GIF と LZW 技術ライセンス情報

サンプル コード

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

サンプル コードについて

マイクロソフトは、明示または黙示、いかなる保証も、市場性および特定目的への適合性の黙示的な保証に限らず、だけのプログラミング例を提供します。この資料は、例示されているプログラミング言語と作成し、プロシージャをデバッグするために使用するツールに精通するいると仮定します。Microsoft support 担当者は、特定のプロシージャの機能について説明することができますが、機能の追加またはお客様固有のニーズを満たすようにプロシージャを作成するのには、次の例は変更されません。
プログラミングが制限されている場合は、マイクロソフト認定パートナー、あるいはマイクロソフト アドバイザリー サービスにお問い合わせくださいする可能性があります。詳細については、次のマイクロソフト Web サイトを参照してください。

マイクロソフトの認定パートナー https://partner.microsoft.com/global/30000104

マイクロソフト アドバイザリー サービス 〜 http://support.microsoft.com/gp/advisoryservice

利用可能なサポート オプションおよびマイクロソフトへの問い合わせ方法の詳細については、次のマイクロソフト Web サイトを参照してください。http://support.microsoft.com/default.aspx?scid=fh です。EN-US です。CNTACTMS

関連情報

GIF コーデックのピクセル形式の詳細については、「サポート技術情報」資料を参照するには、次の文書番号をクリックしてください。
318343 情報: は、8 BPP 形式を使用して、GDI+ GIF ファイル保存されます。
イメージ ファイルのサイズの詳細については、「サポート技術情報」資料を参照するには、次の文書番号をクリックしてください。
312119 PRB: ファイルのサイズの Bitmap クラスの Save メソッドを切り捨てません
このリンクで参照されている資料の使用をについて説明しますが、 ビットマップ クラスのでは System.Drawing 名前空間の。NET Framework」GDI+ するため適用されます。 System.Drawing GDI+ によって実装されます。

用語集

BPP
ピクセルあたりのビットがデジタル化されたイメージの各ピクセルのカラー値を表すために使用されるビットの数です。画像の各ピクセルの色の定義の物理的なレイアウトをについて説明します。共通して一般的に参照先のピクセル形式では 32 BPP、24 BPP、16 BPP、8 BPP、4 BPP、1 BPP などがあります。
8 BPP
8 ビットの 1 バイトに含まれている表記、イメージのピクセル形式。バイト値は実際の赤、緑、青 (RGB) カラーの定義が含まれていますを色テーブルにインデックスとして使用されます。カラー テーブルはインデックスのサイズの 1 バイトであるため、256 色に制限です。
GIF
グラフィックス インターチェンジ形式 - CompuServe で作成された、ストリーム再生可能な画像ファイル形式です。
RGB
赤、緑および青 - それぞれ通常の明示、バイト、およびカラー 3 バイトの組の結果として。

プロパティ

文書番号: 315780 - 最終更新日: 2011年7月25日 - リビジョン: 5.0
キーワード:?
kbhowto kbgdiplus kbbitmap kbdswgdi2003swept kbmt KB315780 KbMtja
機械翻訳の免責
重要: このサポート技術情報 (以下「KB」) は、翻訳者による翻訳の代わりに、マイクロソフト機械翻訳システムによって翻訳されたものです。マイクロソフトは、お客様に、マイクロソフトが提供している全ての KB を日本語でご利用いただけるように、翻訳者による翻訳 KB に加え機械翻訳 KB も提供しています。しかしながら、機械翻訳の品質は翻訳者による翻訳ほど十分ではありません。誤訳や、文法、言葉使い、その他、たとえば日本語を母国語としない方が日本語を話すときに間違えるようなミスを含んでいる可能性があります。マイクロソフトは、機械翻訳の品質、及び KB の内容の誤訳やお客様が KB を利用されたことによって生じた直接または間接的な問題や損害については、いかなる責任も負わないものとします。マイクロソフトは、機械翻訳システムの改善を継続的に行っています。
英語版 KB:315780
Microsoft Knowledge Base の免責: Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。

フィードバック

 

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