2011-06-27 8 views
4

私はユーザーが希望の背景色を持つテキスト以外の単純なイメージを作成できるようにするアプリを持っています。ユーザーはSystem.Windows.Forms.ColorDialogから色を選択し、それを使用してテキストの色と背景の色を設定できます。透明な背景でgifを保存するにはどうすればよいですか?

背景色を透明に設定することができます(私は透明度の基準としてColor.Transparentを使用します)。選択後、テキストと透明度を正しく表示するプレビュー画像を更新します。しかし、私が画像を保存するときには、画像をgifとして保存するための透過性を得ることができません。

私はメソッドを使用して、トランスペアレンシーの色を設定する必要があることを示すthis articleが見つかりました。

保存操作を呼び出す前に、メモリに保存されている画像を背景/透明色として黒で再描画してから、画像を保存する前にメモリ内の画像にMakeTransperentメソッドを呼び出します。それでも、画像は背景として黒で保存されます。

何が間違っていますか?


EDIT:ここに関連コードがあります。

これはイメージを作成する方法です。 overrideBG変数は、透明色をgifの非アルファ色に設定する必要があるかどうかを指定するために使用されます。

void ReDrawImage(bool overrideBG = false) //My method that draws the image in memory. 
{ 
    //My In Memory Image creation 
    img = new Bitmap(sz.Width, sz.Height); 
    Graphics gfx = Graphics.FromImage(img); 

    ... 

    //This portion of code sets the BG color to what should be the transparency color, if the BG is transparent 
    if (overrideBG) 
     { 
      gfx.Clear(TransparentColor); //TransparentColor = Black, unless Text Color is Black. If so, it equals White. 
     } 
     else 
     { 
      gfx.Clear(BackColorPreview.BackColor); 
     } 

    //Followed by code that writes the text. 
} 

//This is the save method (Assume we are always drawing a transparent background.) 
Save() 
{ 
    ReDrawImage(true); 
    img.MakeTransparent(TransparentColor); //I've also tried moving this line before the ReDrawImage call 
    img.Save(SaveFile.FileName, ImageFormat.Gif); 
    ReDrawImage(); 
} 
+0

ようになります。 – lincolnk

答えて

3

明らかにMakeTransparentとgifに問題があります。私はthis postを見つけました。これは、メモリ内のイメージバイトを変更する方法を提供します。ここでは、構文エラーが修正されたポストのコードサンプルを示します。

/// <summary> 
/// Returns a transparent background GIF image from the specified Bitmap. 
/// </summary> 
/// <param name="bitmap">The Bitmap to make transparent.</param> 
/// <param name="color">The Color to make transparent.</param> 
/// <returns>New Bitmap containing a transparent background gif.</returns> 
public static Bitmap MakeTransparentGif(Bitmap bitmap, Color color) 
{ 
    byte R = color.R; 
    byte G = color.G; 
    byte B = color.B; 
    MemoryStream fin = new MemoryStream(); 
    bitmap.Save(fin, System.Drawing.Imaging.ImageFormat.Gif); 
    MemoryStream fout = new MemoryStream((int)fin.Length); 
    int count = 0; 
    byte[] buf = new byte[256]; 
    byte transparentIdx = 0; 
    fin.Seek(0, SeekOrigin.Begin); 
    //header 
    count = fin.Read(buf, 0, 13); 
    if ((buf[0] != 71) || (buf[1] != 73) || (buf[2] != 70)) return null; //GIF 
    fout.Write(buf, 0, 13); 
    int i = 0; 
    if ((buf[10] & 0x80) > 0) 
    { 
     i = 1 << ((buf[10] & 7) + 1) == 256 ? 256 : 0; 
    } 
    for (; i != 0; i--) 
    { 
     fin.Read(buf, 0, 3); 
     if ((buf[0] == R) && (buf[1] == G) && (buf[2] == B)) 
     { 
      transparentIdx = (byte)(256 - i); 
     } 
     fout.Write(buf, 0, 3); 
    } 
    bool gcePresent = false; 
    while (true) 
    { 
     fin.Read(buf, 0, 1); 
     fout.Write(buf, 0, 1); 
     if (buf[0] != 0x21) break; 
     fin.Read(buf, 0, 1); 
     fout.Write(buf, 0, 1); 
     gcePresent = (buf[0] == 0xf9); 
     while (true) 
     { 
      fin.Read(buf, 0, 1); 
      fout.Write(buf, 0, 1); 
      if (buf[0] == 0) break; 
      count = buf[0]; 
      if (fin.Read(buf, 0, count) != count) return null; 
      if (gcePresent) 
      { 
       if (count == 4) 
       { 
        buf[0] |= 0x01; 
        buf[3] = transparentIdx; 
       } 
      } 
      fout.Write(buf, 0, count); 
     } 
    } 
    while (count > 0) 
    { 
     count = fin.Read(buf, 0, 1); 
     fout.Write(buf, 0, 1); 
    } 
    fin.Close(); 
    fout.Flush(); 
    return new Bitmap(fout); 
} 

私はハンスのサンプル(gif部品を置き換える)で試してみました。

あなたのコードは、あなたのコードを投稿

img = MakeTransparent(img, TransparentColor); 
img.Save(SaveFile.FileName, ImageFormat.Gif); 
+0

これは私が望んでいた答えではありませんでしたが、それは働いたものです。ありがとうございました。 – RLH

+0

それは私の側で動作していません:( – Nofuzy

2

GDIバージョン1.10は、透明色を格納するためのプロパティをサポートし、プロパティID 20740.私はそれがこのテストコードを使用してWindows 7上のGIFエンコーダによって慣れる参照:

 var bmp = new Bitmap(100, 100, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 
     using (var gr = Graphics.FromImage(bmp)) { 
      gr.Clear(Color.Blue); 
      gr.FillRectangle(Brushes.Red, new Rectangle(10, 10, 80, 80)); 
     } 
     bmp.MakeTransparent(Color.Red); 
     bmp.Save(@"c:\temp\test.gif", System.Drawing.Imaging.ImageFormat.Gif); 

このコードは正しくビットマップを復元します。

private static Bitmap LoadGif(string path) { 
     var bmp = new Bitmap(path); 
     bool found = false; 
     foreach (System.Drawing.Imaging.PropertyItem item in bmp.PropertyItems) { 
      if (item.Id == 20740) { 
       int paletteIndex = item.Value[0]; 
       Color backGround = bmp.Palette.Entries[paletteIndex]; 
       bmp.MakeTransparent(backGround); 
       found = true; 
       break; 
      } 
     } 
     // Property missing, punt at the color of the lower-left pixel 
     //if (!found) bmp.MakeTransparent(); 
     return bmp; 
    } 

これは以前のバージョンのGDI +でも動作するかどうかはわかりませんが、私はもうXPを持っていません。 SDKには、Vistaに最初に同梱されたバージョン1.10が明示されています。

+0

これは本質的に私がやっていることです。私のプロセスは複数の方法に分かれています。また、アプリケーションにイメージを復元する必要もありません。 – RLH

+1

私はそれが本当に何を意味するか分かりません。画像を見るためにどのようなプログラムを使用していても、プロパティ項目を使用していないようです。別のものを試してみるか、自分で書きます。 –

+0

PictureBoxに表示されるメモリに保存されているイメージを作成します。ユーザーがイメージを保存すると、メモリ内イメージ(img)がgifファイルに書き込まれます。私のプロセスは、ReDrawImageメソッドでイメージを操作し、ファイルをSaveメソッドで保存することを除いて、最初のコードサンプルで説明したとおりです。 – RLH

関連する問題