TImageで矩形を高速で描画するには?

解決


totonica  2006-02-27 03:00:21  No: 20230

皆様はじめまして。
TImageで画像を表示し、その画像にTImageのMouseMoveイベントで
マウスポインタを中心に矩形を描画しているのですが、
どうにも画像のサイズが大きくなるとコマ送りのようになってしまいます。
(画像サイズがXGAを超え始めるともたつきはじめて、
SXGA以上のサイズになるとかなりそれがひどくなります。)
画像サイズが大きくなっても描画を高速で行えるようにしたいのですが、
どのようにすればいいのでしょうか?
どなたかアドバイスよろしくお願いします。

コードは以下のようになっています。

procedure TDVTForm.DrawRectImage;
var
  BackImage: TBitmap;
  DRect: TRect;
  Pos: TPoint;
begin
  BackImage:= TBitmap.Create;
  try
    begin
      BackImage.Assign(ZoomedImage);
      BackImage.Canvas.Pen.Mode:= pmNot;
      BackImage.Canvas.Pen.Width:= 1;
      if Control.Decided = True then
      begin
        BackImage.Canvas.Brush.Style:= bsSolid;
      end
      else
      begin
        BackImage.Canvas.Brush.Style:= bsClear;
      end;
      Pos.X:= Control.StartX;
      Pos.Y:= Control.StartY;
      DRect.TopLeft:= Pos;
      DRect.Right:= Control.StartX +
       (WidthPLE.IntValue - 1) * Control.Zoom div 100;
      DRect.Bottom:= Control.StartY +
       (HeightPLE.IntValue - 1) * Control.Zoom div 100;
      BackImage.Canvas.PenPos:= Pos;
      BackImage.Canvas.Rectangle(DRect);
      OImage.Picture.Bitmap.Assign(BackImage);
    end;
  finally
    begin
      BackImage.Free;
    end;
  end;
end;


ママん  2006-02-27 09:17:59  No: 20231

グラフィックの高速描画についてはその目的、ハードウェア環境に大きく依存するため一概に言えないと思います。
普通にDIBを扱うのであれば、
・描く必要の無い領域は明示的に描かない
・重複する描画はしない
・なるべく大きなバッファを取りその中で作業を行う
なんてとこでしょうか?
TImageは汎用性が高い分、高速描画には不向きです。

※コードを示しているようですが、未定義の変数がありますし正直何がしたいのか分かりません。


totonica  2006-02-27 20:41:47  No: 20232

ママんさんご回答ありがとうございます。
コードの方はそのまま引っ張ってきてしまいました。
分かりづらくて申し訳ありません。

TImageが高速な描画に向いてないと言うことで、
TPaintBoxを使ったところかなりマシな動きになりました。
ご教授ありがとうございました。


さどやま  URL  2006-02-27 21:21:20  No: 20233

> グラフィックの高速描画についてはその目的、ハードウェア環境に大きく依存するため一概に言えないと思います。
  そうですね。
  OS, CPU, 実行前残メモリ、モニタの仕様なども必要でしょう。
  「一般のモニタは、1024 * 768 で最適に動作する仕様になっている」と読んだ覚えがありますが、最近は21インチ以上もかなり普及してきているのでそうとも言えないでしょう。
  ただ、一般論としてのおおまかな傾向については実験すれば出るでしょうが、「解決」する前にテストする余裕があればお知らせします。

> 正直何がしたいのか分かりません
  同感ですが、それはよいとして。
  
  通常 Bitmap.Canvas 上に矩形を描く場合は FrameRect, Polygon, MoveTo/LineTo を使いますが、
  Rectangle となると塗りつぶしになりますので、当然時間がかかります。
  しかし、塗りつぶす必要性があるのでしょう。

  一つ疑問なのは、totanica さんが実行しているモニタの解像度です。
  私の場合 1152 * 864 を常時使っていますが、矩形サイズ XGS, SXGA 以上となると縮小して描画しないと ScrollBar を必要としますし、矩形全体を一目で確認できないので不便です。

  推測では、実寸で描画しているのではなく、縮小表示した画像に矩形描画しているのではないかと思います。
  (例えば、TImage.Stretch := true)
  もしそうであれば、
  ZoomedImage そのものを描画サイズに縮小した Bitmap を StretchDraw などでまず作成し、その上に矩形描画表示すれば劇的に速くなるはずです。
  当然座標変換がいちいち必要になりコードは面倒になりますが、そういう演算はコンピュータの得意分野なので、処理にはほとんど時間を要しません。
  矩形の座標指定はマウスでしているとの事ですから、通常マウスに手を持っていく間に StretchDraw は実行されてしまうので、その処理時間は無視できるでしょう。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加