GDI+を用いたjpeg保存その2
先日のトピックの続きです。
id:n-trino:20130913#p1
ピクセル一個ずつ転送というのは効率悪いから一気に転送出来ないかな?ロックして先頭ポインタ持ってこれないかなと思ってたらやっぱり出来ました。メソッド名もそのまんまでした(^^;
//ビットマップをロックする Gdiplus::BitmapData bitmap_data; bmp.LockBits( nullptr, Gdiplus::ImageLockModeRead|Gdiplus::ImageLockModeWrite, PixelFormat32bppRGB, &bitmap_data ); //データを転送する。 const unsigned char* pSrcPix = aRGBImage; unsigned char* aDstPix = reinterpret_cast< unsigned char* >( bitmap_data.Scan0 ); for( int iY = 0; iY < iSizeY; ++iY ){ unsigned char* pDstPix = aDstPix + iY * bitmap_data.Stride; for( int iX = 0; iX < iSizeX; ++iX ){ pDstPix[0] = pSrcPix[0]; pDstPix[1] = pSrcPix[1]; pDstPix[2] = pSrcPix[2]; pSrcPix += 3;//24bit pDstPix += 4;//32bit } } //ロックを外す。 bmp.UnlockBits( &bitmap_data );
BitmapDataという構造体に先頭ポインタやその他データが入ってきます。このうち、Strideというメンバはいわゆるビットマップの横幅です。通常、ビットマップの横幅は4byteでアラインメントされているので必ずしもYのサイズに一致しないので注意が必要です。
普通に考えたらこちらの方がポインタを直接叩いているので速いはずですがひょっとしたらロック・アンロック自体が重い可能性もありますが・・・面倒なのでベンチは取っていませんorz
余談ですが、ある数値を4の倍数に切り上げる計算方法。
int align = (size + 3) & ~3;
まあ定番ですが。