ここでは、以前ロジックを考えた『漫画カメラ加工』をしてみる。
で、調査。
だいたい私のやりたいことって、HELPとか見てもググってもダメな場合が多い。
また、
こんなとこ(http://docwiki.embarcadero.com/Libraries/XE6/ja/メインページ)
なんて見ても、検索も表示も遅すぎてだれてしまうだけでなく、結局、
【このトピックには現在ドキュメントが存在しません。「ノート」を利用してこのトピックの改良について話しあうことができます。】
なんていう表示をシレっとしてくるのだ。
で、とりあえず、fmx/FMX.Graphics.hppを眺める。
だいたい、GetPixelとかSetPixelなんていう単語を検索するのだ。
うん。どうやら、【TBitmapData】あたりだな。。。
で、これが引数になるやつは、、、
【TBitmap::Map】、【TBitmap::Unmap】あたりかな。。
ということで、
(1)Timage::Bitmap::LoadFromFileでファイルをLOAD。
(2)Timage::Bitmap::MapでTBitmapDataをセット
(3)TBitmapData::Dataがどうやらデータへのポインタ。
で、テストコード。
- TBitmapData B;
- TI->Bitmap->Map(TMapAccess::maReadWrite,B);
- unsigned char* cp = (unsigned char*)B.Data;
- DIB.setSize(B.Width,B.Height);//DIBは自前の画像処理クラス
- memcpy(DIB.getCp(),cp,B.Width*B.Height*4);//4は本来はBytesPerPixel
- DIB.goManga();//goMangaは漫画カメラフィルタ
- memcpy(cp,DIB.getCp(),B.Width*B.Height*4);
- TI->Bitmap->Unmap(B);
で、テスト。→アクセス例外!
そこであれこれやってみて、、TBitmapDataを見直す。
うん。【GetScanline】という関数がある。
ってことは、、画像データが全てメモリ上にあるわけでは無いと予測。
だからmemcpyがオーバーランして例外に違いない。
きっと、使うとこ周辺だけマッピングされてるんだろね。
だって、関数が【Map】だったし!
ということで、コードを改修。1行ずつメモリ内容をCOPYして戻す。
※DIBクラスは全てOnMemory。
- TBitmapData B;
- TI->Bitmap->Map(TMapAccess::maReadWrite,B);
- DIB.setSize(B.Width,B.Height);
- for(int y=0;y<B.Height;y++) DIB.setLineVal(y,B.GetScanline(y));
- DIB.goManga2();
- for(int y=0;y<B.Height;y++) DIB.copLineVal(y,B.GetScanline(y));
- TI->Bitmap->Unmap(B);
で、結果。
うん。大丈夫ですね。
★変換前 ★変換後


0 件のコメント:
コメントを投稿