Delphi6で画像のちらつきをなくすには?

解決


やっさん  2005-04-23 09:00:27  No: 14427

Delphi6でImageに画像を再描画する時にちらつくのですが,この原因と,解決策を
教えて頂けると助かります.いろいろ試してはいるのですが,完全にちらつきが無くならず困っております.よろしくお願いします.


Mr.XRAY  URL  2005-04-23 09:58:57  No: 14428

>Delphi6でImageに画像を再描画する時にちらつくのですが

TImageの親にもよりますが(つまりコーディングによる),Form1に直接
配置しているのであれば,例えば

Form1.DoubleBuffered:=True;

とすれば効果があるかも知れません.DoubleBufferedプロパティは,
TWinControlから派生したコントロールでないと存在しませんので,
TImageを配置しているコントロールを,ヘルプの[継承]のところから
調べてみて下さい.


メラトニン  2005-04-23 18:09:13  No: 14429

どんなコントロールでも基本的にはWindowsに再描画をお願いすることがちらつきの原因になります。
WM_ERASEBKGNDメッセージに0を入れてあげて全部自前で描画させればちらつきは起こりません。
TImageに再描画をお願いすると、画面を一旦背景色で塗りつぶした後、画像を表示させますので、再描画を繰り返す用途には向いていないと思います。
手軽にだったらPaintBoxが良いのではないでしょうか?


sadoyama  URL  2005-04-23 23:14:17  No: 14430

Delphi6 の TImage にはバグがあります。
UpDate すると直ります。

それでもちらつきが直らないことが有りえます。
例えば矩形を描き、マウスでその矩形をドラッグ移動させる場合、
(それだけなら問題はないのですが)
スクロールさせるとどうしてもちらつきが出ます。
そのような場合には、
Frm1.DoubleBuffered や ScrollBox1.DoubleBuffered を使うしかありません。
DoubleBuffered は動きが重たくなるので、できれば使わずに済ませたいものです。。


  2005-04-23 23:17:54  No: 14431

Mr.XRAYさん,メラトニンさん早速のアドバイスありがとうございます.
Imageの配置されていた場所がpanelでしたので

 Form1.Panel1.DoubleBuffered:=True;

にした所,完全にちらつきを消す事に成功しました.
本当に助かりました.これで日々の目の疲れから解放されます.

ところで,メラトニンさんに質問なのですが,WM_ERASEBKGNDメッセージ
に0を入れて全部自前で描画する方法は,実際どのようにするとよいのでしょうか?
私はまだDelphiの経験が浅いもので,再描画時にWM_ERASEBKGNDメッセージがWindowsに送られていて,そのメッセージを無視することができればちらつきが
なくなるという情報はあったのですが,やり方が分からず困っておりました.
出来れば教えていただきたいのですが.


やっさん  2005-04-23 23:19:19  No: 14432

すいません.
上の発言者は私です.


sadoyama  URL  2005-04-23 23:30:11  No: 14433

Delphi6 TImage のバグは、次の投稿以下で論議されています。
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=080262


やっさん  2005-04-23 23:31:05  No: 14434

sadoyamaさんありがとうございます.

Delphi6のTImage自体にバグがあったんですね・・・.
知りませんでした.
また,Doublebfferedは重くなるという事で,それだとすると
一番最適なのは,WM_ERASEBKGNDメッセージに0を入れるという
方法になるのでしょうか?


sadoyama  URL  2005-04-24 00:48:21  No: 14435

WM_ERASEBKGND はウィンドウの背景を書き換える伝令メッセージですので、
たとえば私が例にあげたような場合のちらつきの防止にはまったく無意味です。
したがって、DoubleBuffered を使うしかないのですが、
次のように、その使用を最小限に抑える工夫をしています。

  if ScrollBox.VertScrollBar.Visible or
     ScrollBox.HorzScrollBar.Visible then
     ScrollBox.DoubleBuffered := true
  else
     ScrollBox.DoubleBuffered := false;


やっさん  2005-04-24 02:25:26  No: 14436

DoubleBufferedを使う時はTRUEにして,使わない時はFALSEにしておくことで
メモリ使用量を軽くするわけですね.
その点は用途に合わせて自分なりに工夫してみたいと思います.
sadoyamaさん,いろいろ教えていただきありがとうございます.
またお世話になる時が来ると思うので,その時はまたアドバイスしていただけ
れば助かります.ありがとうございました.


やっさん  2005-04-24 02:26:35  No: 14437

解決をチェックし忘れました.


メラトニン  2005-04-24 02:38:08  No: 14438

とりあえず下記のソースを参考にしてForm1に
Image1を貼り付けてください
画像は適当な大きさのものをあらかじめ貼り付けてください。
Form1をリサイズするとImage1がちらつくことが分かります。
ちらつきが確認できたら
Form1.DoubleBuffered:=True;
にしてみてください、
さらにちらつきがなくなるのを確認したら
Form1.DoubleBuffered:=False;
にしてからコメントアウトを外してください。
とすると、DoubleBufferedを使用しないでちらつかない描画ができます。
ですが、このようなことを行うともはやTImageやTPaintBoxを使用するより自分でコントロールを作成する方が手っ取り早くなります。

>>sadoyama
>>Frm1.DoubleBuffered や ScrollBox1.DoubleBuffered を使うしかありません。
そんな事はありません。ただ簡単では無いだけです。

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, jpeg;

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure FormCreate(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    { Private 宣言 }
    //procedure WMEraseBkGnd(var Msg: TMessage); message WM_ERASEBKGND;
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//コメントを外して比較してください
//その際FormPaintのコメントアウトした一文も外してください
//procedure TForm1.WMEraseBkGnd(var Msg: TMessage);
//begin
//  Msg.Result:=0;
//end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Image1.Align:=alNone;
  Image1.AutoSize:=True;
  //切り替えてみてください
  DoubleBuffered:=False;
  Canvas.Pen.Color:=Canvas.Brush.Color;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  //Canvas.Rectangle(0,0,ClientWidth ,ClientHeight);
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Image1.Left:=ClientWidth  - Image1.Width - 50;
  Image1.Top :=ClientHeight - Image1.Height - 50;
end;

end.


やっさん  2005-04-24 04:08:15  No: 14439

教えて頂いたソースを参考にプログラムを作成した所,
確かに,DoubleBuffered:=Flase; の状態でちらつきはなくなりました!
いろいろと方法はあるんですね〜.
メモリの面から考えるとこちらの方法をとった方がよさそうですね.
今回,メラトニンさんをはじめ,sadoyamaさん,Mr.XRAYさんからのアドバイスの
おかげで,本当に勉強になりました.
今後,Delphiを使いこなしていく上で,また壁にぶち当たる時がくると思います.
是非その時は,またアドバイスを頂けたら幸いです.
ありがとうございました.


jok  2005-04-24 04:08:30  No: 14440

> メラトニン さん
> WM_ERASEBKGNDメッセージに0を入れてあげて全部自前で描画させればちらつきは起こりません。

ここが参考になるでしょう。

http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=077643
http://www2.big.or.jp/~osamu/Delphi/delphi-browse.cgi?index=077653


やっさん  2005-04-26 19:52:14  No: 14441

jokさんありがとうございます!!
参考にさせていただきます.
今後ともよろしくお願いします.


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

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






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