ネイティブ関数を使用して画像を読み取ろうとしています。そのために、私はこのコードを使用してみました:
var result = new Bitmap((int)info.width,(int)info.height,PixelFormat.Format24bppRgb);
var data = result.LockBits(new Rectangle(0, 0, result.Width, result.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
bool success = ReadFullImage(data.Scan0, ref info, ref png);
result.UnlockBits(data);
if (!success)
return null;
else
{
return result;
}
ここでinfo
、は画像の高さと幅を含み、はラッパーでpng
ありpng_struct
、ReadFullImage
はラッパーpng_read_image
です。ただし、アクセス違反が発生していました(例外コード0xc0000005)。
その後、私は値data
が保持されていることを調べました、私はこれを発見しました:
data {System.Drawing.Imaging.BitmapData} System.Drawing.Imaging.BitmapData
Height 1557 int
m_bmpdata {Microsoft.AGL.Drawing.AGL_BITMAPDATA} Microsoft.AGL.Drawing.AGL_BITMAPDATA
PixelFormat Format24bppRgb System.Drawing.Imaging.PixelFormat
Scan0 1638432 System.IntPtr
Stride 1512 int
Width 503 int
ここに一見問題があります。書き込まれている行のサイズは2012バイトですが、使用可能なのは1512のみであり、やがて割り当てられたメモリの外部で書き込みが試行されます。
問題は、フォーマットがピクセルあたり24ビットであるにもかかわらず、行のサイズが1512 = 503 * 3 + 3しかないのはなぜですか。また、十分なメモリを割り当ててビットマップにフィードするにはどうすればよいでしょうか。
あるいは、互換性のある方法でpngをlibpngで読み取ることはできますか?
更新:ReadFullImageはのDllImportです
extern "C" void read_image_full( unsigned char * buffer,pngImageInfo* info,pngDataStructures* png)
{
png_bytepp row_pointers = new png_bytep[info->height];
for (unsigned int i = 0; i < info->height; ++i)
row_pointers[i] = buffer + i*info->rowbytes;
png_read_image(png->png_struct_field, row_pointers);
return true;
}
そして、rowbytesはpng_get_rowbytesを介して取得されます。