画面に表示されてる画像をOpenCVに食わせようとしてハマった
まず、CBitmap インスタンスからビットマップデータを取り出す CBitmapT::GetBitmapBits が定義されてない。
Win32 APIだけど、CEでは使えないのだ。
これはデータから直接抽出できる。CBitmap bmpImage に画像が入ってるとして、
DIBSECTION dibsection;
::GetObject(bmpImage, sizeof(dibsection), &dibsection);
BITMAP bitmap = dibsection.dsBm;
BITMAP * data = (BITMAP *)bitmap.bmBits;
この data をOpenCV の IplImage に与えればいいかと思うけれど、そうはいかない。
IplImage * image = cvCreateImage(size, IPL_DEPTH_8S, 3); cvSetData(image, data, step); CAtlStringA bmpfile = _T("\\Storage Card\\bmp.jpg"); cvSaveImage(bmpfile, image);
cvSaveImage を実行したところで、エラーが出た。
Data Abort: Thread=97add8a0 Proc=80096f40 'ImageView.exe' AKY=00004001 PC=00fd8dd8(cxcore200d.dll+0x00058dd8) RA=00fbb0a0(cxcore200d.dll+0x0003b0a0) BVA=1e1eb000 FSR=00000407
data をファイルに書き出してみると、ずいぶん小さいファイルになった。想定の2/3のサイズ……というところでオチが読めたあなたは、同じことでハマったことがすでにあると見た。
bitmap.bmWidthHeight が、bitmap.bmWidth の2倍の値しかない……つまり、24ビットカラーを期待してたのに16ビットカラーだった。
そしてOpenCV は16ビットカラーをサポートしていないし、減色されたデータを与えてもしょうがない。
CBitmap から取ってくるなんて横着をせずに、画像ファイルは別途 IplImage に読み込んでおくべきだ。
WM6 用にコンパイルした OpenCV というか libpng が、なぜかちゃんと動かない*1という問題が別にあったりするけれど。