• 締切済み

ビットマップの描画方法

こん○○は。 BCB5を使ってますが、 高速にビットマップを描画する方法はないでしょうか? TImage コンポーネントを使用し Picture->Bitmap->Canvas->Pixels[x][y] へ SDKから取得したカメラ画像データをTColor RGB(r,g,b)で設定しています。 フォームに画像が表示されるまで1秒ほどかかるためコマ送り状態になっています。

  • QooQ
  • お礼率0% (0/4)

みんなの回答

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.4

No.3に引用したコードだとImgData[pnt]の先頭バイトをそのまま3回コピーしてますよね。 ImgDataも32ビットマップデータということですから、ImgData[pnt]から始まる32ビット=4バイト(または4バイト目は省略して3バイト)をコピーする必要があるのではないでしょうか? for( int j=0 ; j<pBitmap->Height; j++ ){  Byte *rgb = (Byte *)pBitmap->ScanLine[j];  for(int i=0;i<pBitmap->Width;i++){   int pnt = j * pBitmap->Width + i;//pntはintですね?   memcpy( &rgb[i*4], &ImgData[pnt], 3 );//コピーするのは3バイトにしてます  } } ImgDataが配列またはポインタならポインタ演算を使ったほうがすっきりするかもしれません。 for( int j=0 ; j<pBitmap->Height; j++ ){  Byte *rgb = (Byte *)pBitmap->ScanLine[j];  Byte *src = (Byte *)(ImgData + j * pBitmap->Width);  for(int i=0;i<pBitmap->Width;i++){   memcpy( rgb, src, 3 );   rgb+=4, src+=4;  } } あと、蛇足ですが、効率を考えるならpBitmapはフォームメンバにするかして一度だけnew/deleteするようにしたほうがいいですね。 以上ImgDataほかの詳細が分からないのであまり自信がありません。

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.3

No.1の補足に関して ぱっと見で仔細に検討してないのですが、  rgb[i*4+2] = (Byte)ImgData[pnt];  rgb[i*4+1] = (Byte)ImgData[pnt];  rgb[i*4+0] = (Byte)ImgData[pnt]; これでかまわないのですか?

QooQ
質問者

補足

画像データ処理については新参者であり思考錯誤しておるところでもあります。 いろいろネットで調べサンプルを試してますが この辺のデータコンバートに問題ありでしょうか

回答No.2

はじめまして。 一般にPixelsは動作が非常に遅いです。 scanlineを使ってください。

  • KoHal
  • ベストアンサー率60% (110/181)
回答No.1

TImageへの書き込みはかなりのオーバーヘッドが生じます。 とりあえず書込み用のTBitmapを用意して、そこに画面1枚書込んだところでTImageに反映させるようにしてみて下さい。 それだけであるていど改善されると思います。

QooQ
質問者

補足

TBitmapを用意しScanLineへ書き込みTImageに反映させてみました。 カメラの移動に対しスムーズに反応はしてますが、表示画像全体がグレーの網掛けになっています。 取り込む画像データ( ImgData[ ] )は、32bitsビットマップデータのデータ部と同じ形式です。 データの扱いに問題ありでしょうか? Graphics::TBitmap *pBitmap; pBitmap = new Graphics::TBitmap(); pBitmap->Width = 680; pBitmap->Height = 512; pBitmap->PixelFormat = pf32bit; for( int j=0 ; j<pBitmap->Height; j++ ){  Byte *rgb = (Byte *)pBitmap->ScanLine[j];  for(int i=0;i<pBitmap->Width;i++){   pnt = j * pBitmap->Width + i;   rgb[i*4+2] = (Byte)ImgData[pnt];   rgb[i*4+1] = (Byte)ImgData[pnt];   rgb[i*4+0] = (Byte)ImgData[pnt];  } } pImage->Canvas->Draw( 0 , 0 , pBitmap ); pImage->Refresh(); delete pBitmap;

関連するQ&A

  • 【Delphi】 Canvasへの描画について疑問

    まず、Form1の上にimage1を配置し、その奥にTGraphicControlを継承した描画コンポーネントを置いています。 そして、image1のTransparentを設定し、描画が見えるようにします。 つまりimage1が窓枠で、ガラス(透過)越しに風景の描画が見えると考えてください。 そこで、描画コンポーネント側でTGraphicControl.Canvas.Drawで風景の描画を行います。すると、描画したものが窓枠より手前に表示されてしまい、窓枠&透過の意味が無くなってしまいました。 image1の下に普通のTimageを置き、Timage.Canvas.Drawで行うと、異常は起きません。何故なのでしょうか・・・?

  • ビットマップに描画をしてピクチャーコントロールに貼り付けるためには?

    ビットマップに描画をしてピクチャーコントロールに貼り付けるためには どうすればよいでしょうか? ネットで検索しましたそして、 下のようなコードを書きましたがうまくゆきません。 void CXXXView::OnButton() { CStatic m_ctlImage; // ピクチャーボックスに関連付けした変数 CBitmap m_bmpImage; // ピクチャーボックスに貼り付けるイメージ CDC m_dcImage; // Bitmap描画用のDC CDC* pDC = m_ctlImage.GetDC(); m_dcImage.CreateCompatibleDC(pDC); CRect Cltsz; picture1.GetClientRect(&Cltsz); m_bmpImage.CreateCompatibleBitmap(pDC,Cltsz.Width(),Cltsz.Height()); CBitmap* pOld=m_dcImage.SelectObject(&m_bmpImage); CPen myPEN(PS_SOLID,5,RGB(0,0,255)); CPen* oldPEN=m_dcImage.SelectObject(&myPEN); m_dcImage.MoveTo(10,10); m_dcImage.LineTo(100,100); m_dcImage.SelectObject(oldPEN); m_dcImage.SelectObject(pOld); m_ctlImage.SetBitmap(m_bmpImage); } この様にしましたが、ピクチャーコントロールには 何も描画されません、 何故でしょうか? VS2005で、ボタンをクリックした イベントで描画する場合です、 直線とかは、問題なく描画できました。 ビットマップに描画して貼り付けたいのです、 よろしくお願いします

  • C# ビットマップの描画を高速にしたい

    C# ビットマップの描画を高速にしたいです。 ピクチャーコントロールでは限界でして、DirectXやDirectShow、OpenGLなど他のライブラリを用いて簡単に実装したいのです。 何かおすすめのライブラリがありましたらお教え頂けないでしょうか?サンプルなどが多いものですと・・非常に助かります。

  • アクションスクリプト ビットマップデータ 描画

    Flashゲーム作成のため、アクションスクリプトを学び始めた初心者です。 ゲーム作成中にプレイヤーがミスをした場合、"MISS!!"という文字を画面に描画し、下から上へスクロールさせる処理を考えています。 ビットマップデータにテキストフィールドで指定したテキストを描画しているのですが、その描画位置を指定できなくて困っています。 canvas = new BitmapData(WIDTH, HEIGHT, true, 0x0);// 透明、初期色0x00000000 var bitmap:Bitmap = new Bitmap(canvas); bitmap.scaleX = bitmap.scaleY = 1;// 1倍表示 addChild(bitmap); var tf:TextField = new TextField(); tf.defaultTextFormat = new TextFormat("MS ゴシック", 50, 0xFF0E0E ,true); tf.width = stage.stageWidth; // 幅 tf.height = 50; tf.autoSize = TextFieldAutoSize.CENTER; tf.y = 240; tf.text = "MISS!!"; canvas.draw(tf); これで実行すると、画面上にMISS!!と表示されて、tf=240が適応されません、どうしたらテキストの表示位置の縦方向の位置を変えることができるのでしょうか?教えていただきたいです。

    • ベストアンサー
    • Flash
  • OpenGLで描画した画像のピクセル(RGB)を配列に格納したい。

    初めまして。taka-0910と申します。 現在、OpenGLを使って描画した画像のピクセル情報を取得しようと考えています。 しかし、取得したRGBの値が描画したものとまったく異なる値となってしまいます。 glReadPixels()という関数で試していますが、何度修正してもうまくいきません。よろしくお願いします。 プログラムの一部ですがこのようになっています。プログラムが一部分で申し訳ありません width, heightというのは、画像のサイズです。 *pixelsに画素(RGB)の値を格納したいと考えています。 GLubyte *pixels; pixels = ( GLubyte* )malloc( width * height * 3 * (sizeof(GLubyte))); glReadBuffer(GL_FRONT); glPixelStorei( GL_PACK_ALIGNMENT,1 ); glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels ); glFlush();

  • ビットマップを直接編集して背景画像を波打たせる

    質問(1) pixelsは一次元配列で1ラインのx方向の要素を左方向や右方向にシフト量sだけ離れた所へコピーすることにより1ラインの画像のピクセルデータをシフト量sだけずらして波打たせる効果を持たせていることは想像つきますが、これではy方向を考慮した全てのラインをずらすことにはなっていない様な感じがします。y方向はどうなっているのですか? 質問(2) int line = y*bmpdata.Stride/4;で4で割っているのは何故ですか? 質問(3) if(s<0){ //左へコピー for(int x=-s; x<BITMAP_W; x++){ if(x+s>=0){ pixels[line+x+s] = pixels[line+x]; } } } でこのif文の中の条件式x+s>=0はint x=-s;→int x+s=0;…;x++により明らかに常に真ではないですか?もし、そうだとしたらこのif文は必要ないのではないですか? 質問(4) } else if(s>0){ //右へコピー for(int x=BITMAP_W; x>=s; x--){ if(x+s<BITMAP_W){ pixels[line+x] = pixels[line+x-s]; } } } } でこのif文の中の条件式x+s<BITMAP_Wの意味が良く分かりません。 質問(5)(6)(7) for(int y=0; y<BITMAP_H; y++){ … int line = y*bmpdata.Stride/4;の意味が良く分かりません。質問(5) … pixels[line+x+s] = pixels[line+x];でlineを加えているのは何故ですか?質問(6) … pixels[line+x] = pixels[line+x-s];でlineを加えているのは何故ですか?質問(7) C言語、C++言語初心者なので分かりやすく教えて下さい。 宜しくお願いします。 プログラムコード(animation.cpp) //ウェーブエフェクト UINT g_wavecount; const int BITMAP_H = 480; const int BITMAP_W = 320; float g_wavelines[BITMAP_H]; //ウェーブエフェクト初期化 void ResetWave(){ g_wavecount = 0; float r=0, rdelta=3.14f/12;//波の数 float waveh = 3;//波の高さ for(int i=0; i<BITMAP_H; i++){ g_wavelines[i] = sinf(r) * waveh; r += rdelta; } } //ウェーブエフェクト描画 void RenderWave(Gdiplus::Bitmap *bmp){ g_wavecount++; int topline = g_wavecount % BITMAP_H; //ビットマップのロック Gdiplus::BitmapData bmpdata; Gdiplus::Status status = bmp->LockBits( &Gdiplus::Rect(0,0,320,480), Gdiplus::ImageLockModeWrite, bmp->GetPixelFormat(), &bmpdata); if(status != Gdiplus::Ok) return; UINT* pixels = (UINT*)bmpdata.Scan0; //←この行から下のコードが全部分からない。 //ビットマップを加工する for(int y=0; y<BITMAP_H; y++){ //シフト量を取得 int s = (int)g_wavelines[(topline+y)%BITMAP_H]; int line = y*bmpdata.Stride/4; //ピクセルコピー if(s<0){ //左へコピー for(int x=-s; x<BITMAP_W; x++){ if(x+s>=0){ pixels[line+x+s] = pixels[line+x]; } } } else if(s>0){ //右へコピー for(int x=BITMAP_W; x>=s; x--){ if(x+s<BITMAP_W){ pixels[line+x] = pixels[line+x-s]; } } } } bmp->UnlockBits(&bmpdata); }

  • GDI+のDrawStringを使って文字を滑らかに描画したいのですが。。。

    GDI+のDrawStringを使って文字を滑らかに描画したいのですが。。。 環境は、VC++のWin32プロジェクトです。 WindowのデバイスコンテキストからGraphicsオブジェクトを生成し、DrawStringとすると滑らかに描画されます。 しかし、BitmapオブジェクトからGraphicsオブジェクトを生成し、DrawStringを行うとビットマップフォントのようです。 Graphics g(hdc); g.DrawString(......); -> この場合はなめらか(画像の下の方) しかし、 Bitmap bmp(w, h, PixelFormat32bppARGB); Graphics g (&bmp); g.SetSmootingMode(SmoothingModeHighQuality); g.DrawString(...); -> ジャギが目立つ。(画像の上の方) ビットマップ(メモリ)にスムーズなテキストを描画することはできないのでしょうか? ちなみにフォントはメイリオです。

  • BCB6でStretchDrawを使いたいのですが

    BCB6でStretchDrawを使いたいのですが Formなどに書き出す場合は出来るのですが TBitmapを用意してそこに書き出そうとすると出来ません Graphics::TBitmap *Bitmap1 = new Graphics::TBitmap(); Graphics::TBitmap *Bitmap2 = new Graphics::TBitmap(); Bitmap1 = Image1->Picture->Bitmap; TRect e; e.Top=0; e.Left=0; e.Right = 450; e.Bottom = 450; Bitmap2->Canvas->StretchDraw(e,Bitmap1); Image2->Picture->Assign(Bitmap2); わかりにくいでしょうが よろしくお願いいたします。

  • Bitmap画像の消去について

    やりたいこととして Bitmap画像を表示する前になにかしら背景が描画されています。 そしてボタンを押すとか何かしらイベントが起こったときにBitmap画像を描画します。 そしてまたボタンを押すと背景はそのままでそのBitmap画像だけを消去する ということがしたいです。 今、ピクチャーボックスを使ってBitmap画像を表示することはできます。 ただそのBitmap画像を消去することはできていません。 探しているとピクチャーボックスを白く塗りつぶして、背景を再描画するって方法はあるのですが、いろいろあってその方法は使いたくないです。 Bitmap画像だけを消去する方法はあるのでしょうか? OSはVistaで、VC++2003.netを使っています。 宜しくお願いします。

  • Open CV でBitmap描画の高速化

     現在Open CVとVC++2008のC++/CLIを用いてform上のpictureBoxにカメラ画像を表示するプログラムを作成しています。  プログラムは,http://imagingsolution.blog107.fc2.com/blog-entry-91.htmlのサイトの『IplImageのPictureBoxへの描画』の項を参考にさせていただきました。 カメラ画像の描画だけでしたら,問題なく動作しますが,その他の処理を行うと,全体の動作が遅くなってしまいます。 そこで,どうにかして全体の動作速度あげようと,調べているとBitmapの描画は遅いということはわかりました。 しかし,どのようにすればBitmap描画を高速化出来るのかがわかりません... お分かりになる方がいらっしゃいましたら,何卒ご教授お願い致します。

専門家に質問してみよう