DIBを中心としてデータ管理を行うつもりなので、不透明度は BYTE 配列に保持しておく。

 それを前提に読み取ってみる。

 

void ReadPNG(Gdiplus::Bitmap* pImage , CSize sizeBitmap)

{

    Gdiplus::BitmapData bmpData ;
    BYTE btAlphaSrc ;
    /*******************************************************
    // alpha =   0 : 透過 //
    // alpha = 255 : 完全塗り潰し
   ********************************************************/

    // 1. 初期設定 //
    // (1). 32ビットでない場合 //
    if (pImage->GetPixelFormat() != PixelFormat32bppARGB) return ;

    // (2). 四角形サイズ //
    Gdiplus::Rect rc(0 , 0 , sizeBitmap.cx , sizeBitmap.cy) ;

    // (3). ロック //
    pImage->LockBits(

                    &rc,

                    ImageLockModeRead | ImageLockModeWrite ,

                    PixelFormat32bppARGB ,

                    &bmpData

                ) ;

    // (4). ピクセル当たりのバイト数 //
    UINT BytesPerPixel = 4 ;

    // 2. ピクセルデータへのアドレス //

    // 残念ながら、このあたりは、他の方のコピー //

    BYTE* pixels = NULL ;

    if(bmpData.Stride > 0)
    {
        pixels = (BYTE*)bmpData.Scan0;
    }
    else
    {
        pixels = (BYTE*)bmpData.Scan0 + bmpData.Stride * (sizeBitmap.cy - 1) ;
    }
    // これが、よくわからない //
    UINT stride = abs(bmpData.Stride);

    // 3. 透過部分を列挙 //
    for(int y = 0 ; y < sizeBitmap.cy ; y++)
    {
        for(int x = 0 ; x < sizeBitmap.cx ; x++)
        {
            // (1). ピクセル (x , y) のアドレス //
            BYTE* pCol = pixels + y * stride + BytesPerPixel * x ;


            // (2). b = p[0] , g = p[1] , r = p[2] , a = p[3] //
            btAlphaSrc = (BYTE)pCol[3] ;

            // (3). 不透明度を配列に保存 //

            // 各自記述 //
        } // Next x //
    } // Next y //

    // 5. 解除 //
    pImage->UnlockBits(&bmpData) ;
}


こんな感じでしょう。

GetPixel()、SetPixel()が遅いということで、ピクセルのアドレスを取得して、その値だけを取り出してます。

 

 ファイルを読み取る時だけだから、多少時間がかかっても、そこはいいでしょう。

 

 PNG形式ファイルを解析すると、こんな感じで成功します。