none
bmpから透過情報を持ったPNGへの変換 RRS feed

  • 質問

  • GDI+を使用して、bmpファイルからPNGファイルへ変換して保存しています。
    (Imageクラスのsave使用)
    ここで、ある特定の色を透過させたPNGファイルへ変換・保存することはできるでしょうか?
    .NETを使用せずに行う方法を探しています。

    よろしくお願いします。

    2007年1月26日 15:17

すべての返信

  • 非常にベタな方法なのですが、「GetPixel で各 Pixel の色を抜き出して、特定の色だった場合には SetPixel で Gdiplus::Color::Transparent で書き直す」というのは、どうでしょうか?

    # 半透明…とかでしたら、「α値を設定して書き直す」で。

    確認してみたところ、Gdiplus::Color::Transparent に置き換えた Pixel は透過されているようです。(Paint.NET で確認しました)

     

    2007年1月29日 7:23
  • ちょうど自分でもGetPixel・SetPixelで試して上手くいったところでした。
    ベタな方法ですが仕方ありませんね。

    ありがとうございました。

     

    2007年1月30日 2:08
  • ImageAttributes クラスの SetRemapTable メソッドでマッピングテーブルを作成し、DrawImage メソッドに引き渡せばいいんではないですかね。

    2007年1月30日 3:09
  • 試してみました。DrawImage と SetRemapTable (ImageAttribute) を組み合わせる方がずっと高速に目的を達成できますね。

    # GetPixel, SetPixel の overhead が馬鹿にならない…

    EncoderParameter 1つで解決しそうにはないですし、Hongliang さんの提案されていらっしゃる手法の方が SetPixel/GetPixel よりおすすめです。

     

    2007年1月30日 6:05
  • 一度も画面等に描画することなく透過PNGファイルとして保存したいのですが、Graphics::DrawImage()を使ってColorMapを変更した場合も、その後その変更した画像をPNGファイルとして保存することが可能なのでしょうか?
    可能なようでしたら、Graphicsをファイルとして保存する参考コードを教えていただけると嬉しいです。

    2007年1月31日 1:41
  • Graphics のインスタンスを作成する時に Image を渡すと良いようです。(細かなところは、かなり適当なのですが)次のようなコードでテストしました。

    int
    iTest3 (void)
    {
     Gdiplus::GdiplusStartupInput gdiplusStartupInput;
     ULONG_PTR gdiplusToken;

     Gdiplus::Bitmap* bitmap  = NULL ;
     Gdiplus::Image*  pNewImage = NULL ;
     Gdiplus::Color  col ;
     Gdiplus::ColorMap* pMap ;
     Gdiplus::ImageAttributes* pImageAttr ;
     Gdiplus::Graphics* pGraphics ;
     UINT    x, y, i ;

     if (Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL) != Gdiplus::Ok) {
      _ftprintf (stderr, TEXT ("GdiplusStartup failed.\n")) ;
      return -1 ;
     }
     bitmap = new Gdiplus::Bitmap (L"test.bmp", true) ;
     if (bitmap != NULL) {
      UINT  num;        // number of image encoders
      UINT  size;       // size, in bytes, of the image encoder array
      Gdiplus::ImageCodecInfo* pImageCodecInfo;

      Gdiplus::GetImageEncodersSize (&num, &size) ;
      pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size)) ;
      Gdiplus::GetImageEncoders (num, size, pImageCodecInfo) ;

      for(i = 0; i < num ; i ++) {
       if (! wcscmp ((pImageCodecInfo + i)->MimeType, L"image/png")) {
        break ;
       }
      }
      if (i < num) {
       pMap = new Gdiplus::ColorMap ;
       pMap->oldColor = Gdiplus::Color::White ;
       pMap->newColor = Gdiplus::Color::Transparent ;
       pImageAttr = new Gdiplus::ImageAttributes ;
       pImageAttr->SetRemapTable (1, pMap) ;
       pNewImage = new Gdiplus::Bitmap (bitmap->GetWidth (), bitmap->GetHeight (), PixelFormat32bppARGB) ;
       pGraphics = new Gdiplus::Graphics (pNewImage) ;
       pGraphics->Clear (Gdiplus::Color::Transparent) ;
       pGraphics->DrawImage (bitmap, Gdiplus::RectF (0, 0, bitmap->GetWidth (), bitmap->GetHeight ()), 0, 0, bitmap->GetWidth (), bitmap->GetHeight (), Gdiplus::UnitPixel, pImageAttr) ;
       pNewImage->Save (L"test.png", &(pImageCodecInfo + i)->Clsid) ;
      }
      free(pImageCodecInfo) ;
      delete bitmap ;
      bitmap = NULL ;
     }
     if (pNewImage != NULL)
      delete pNewImage ;
     if (pGraphics != NULL)
      delete pGraphics ;
     Gdiplus::GdiplusShutdown (gdiplusToken) ;
     return 0 ;
    }

     

    2007年1月31日 2:45
  • できました!
    ありがとうございます。大変助かりました。
    2007年1月31日 4:18