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形式ファイルを解析すると、こんな感じで成功します。
