ラベル RGBA の投稿を表示しています。 すべての投稿を表示
ラベル RGBA の投稿を表示しています。 すべての投稿を表示

2014年8月22日金曜日

AppMethodに挑戦(14)簡単に画像加工してみる

では、画像を読み込んでフィルタリングすることを考える。
ここでは、以前ロジックを考えた『漫画カメラ加工』をしてみる。
で、調査。
だいたい私のやりたいことって、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);

で、結果。
うん。大丈夫ですね。
★変換前                 ★変換後
   

2014年8月21日木曜日

AppMethodに挑戦(13) 画像を扱う第一歩→Oneソースマルチプラットフォームの道は険しい。→いや、そうでもないか。

これはまぁバグじゃないんでしょう。きっと。
仕様としてはこの方が美しいと言える部分もあります。
こうなってる理由もわかります。
でも、やっぱいただけないかなー。
だって#ifdefかかなきゃなんないもんね。。。^^;

ということで、画像を扱う第一歩として、
画像を読み込んで表示させて、メモリを操作して線を描画して表示させるなんてことをやってみました。
●TBitmapに読み込む
●TImageにわりつける
TImage::TBitmapのデータポイントを取得する
●直書きしてみる
っとまぁ、そんなとこです。
で、ですね。。。例によって、WIN32とAndroidの結果ですが。。。。

★WIN32       ★Android
  

そうです。線の色が違う。
そしてデータを取ってきたときの内容が違う。
WIN32の方は、B-G-R-Aの順。
Andridの方は、R-G-B-Aの順。
もちろん、理由はなんとなくわかりますけどねー。
でもねーー。。せっかくOneソースなんだから。。。
なんとかして欲しかったなぁーー。


TBitmap* bmp = new TBitmap;

String gfile = TPath::Combine(TPath::GetDocumentsPath(), "gazou.png");
bmp->LoadFromFile(gfile);
TI->Bitmap = bmp;
TBitmapData B;
TI->Bitmap->Map(TMapAccess::maReadWrite,B);
unsigned char* cp = (unsigned char*)B.Data;
AnsiString as;
for(int w=0;w<100;w+=4){
 as.printf("[%02x][%02x][%02x][%02x]",cp[w*4+0],cp[w*4+1],cp[w*4+2],cp[w*4+3]);
 M1->Lines->Add(as);
}
for(int w=0;w<100;w++){
 char* ccp = (char*)B.GetPixelAddr(w,w);
 ccp[0] = 0x0;  
 ccp[1] = 0x0;  
 ccp[2] = 0xff;  
 ccp[3] = 0xff;
 ccp[0+4] = 0x0;  
 ccp[1+4] = 0x0; 
 ccp[2+4] = 0xff;
 ccp[3+4] = 0xff;
 ccp[0+8] = 0x0; 
 ccp[1+8] = 0x0; 
 ccp[2+8] = 0xff;
 ccp[3+8] = 0xff;
}
TI->Bitmap->Unmap(B);