1 名前:デフォルトの名無しさん [2009/02/22(日) 22:10:29 ] Delphi(デルファイ)について、他のスレッドでは書き込めない超低レベル、 もしくは質問者自身何が何だか分からない質問を 勇気を持って書き込むスレッドです。 Delphi使いが優しくコメントを返しますが お礼はDelphiの布教と初心者の救済をお願いします。 <前スレ> くだすれDelphi(超初心者用)その48 pc11.2ch.net/test/read.cgi/tech/1225641040/ <過去スレ> DelWiki避難所(Delphi 関連の過去スレッド) delwiki.info/?%E3%83%AA%E3%83%B3%E3%82%AF%2F%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%83%86%E3%82%A3%2FDelphi%20%E9%96%A2%E9%80%A3%E3%81%AE%E9%81%8E%E5%8E%BB%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89
385 名前:デフォルトの名無しさん mailto:sage [2009/05/01(金) 10:30:37 ] VirtualListViewに256x256のサムネイル画像を並べているのですが、StretchBlt で 縦横比を変えずに縮小するために JpegをTPictureで読み込んでBMP.Assignするときに凄く時間がかかってしまいます 最初は中村氏のBitmapUtils.Stretchを使ってからStretchBltしていましたからもっと時間がかかっていました TVirtualExplorerEasyListviewなどはエクスプローラ並みのスピードで表示されるので方法次第だと思うのですが ソースがないので手法が分かりません どの方向で考えたらいいでしょうか?御指南ください
386 名前:デフォルトの名無しさん mailto:sage [2009/05/01(金) 13:43:04 ] >>385 TJpegImageのScale使うか、 写真ならExifのサムネイルを読み込むか。
387 名前:デフォルトの名無しさん mailto:sage [2009/05/01(金) 14:21:28 ] ありがとうございまし、そんなのもあるのですね D2009のJpeg,GIFImg,pngimageを使っているので型によって縮小方法を変えるんですね ググったら ttp://jane.s89.xrea.com/test/read.cgi/kakolog/1119916964/170-188 がでました。サンプルソ−スも生きていて落とせましたので読んでみます でも、usesするだけでTImageとかでpngとか読めるんだから(これが凄いけど) TImageListとTListViewも対応してくれるのが一番嬉しいんですよね
388 名前:デフォルトの名無しさん mailto:sage [2009/05/01(金) 14:23:12 ] ソースだと思ったらJane本体だったorz これだけがヒントですね 188 :Jane使いの名無しさん:05/07/27 00:00:41 ID:6kBZoROZ >>174 ・TJpegImage.Scale //←基本的にこれ ・TbitmapはDIBにする ・Jpeg.pasとiijのライブラリ改造 TApiBitmapとTBitmapで検索して掛かったとこちょっと 変えてみただけ
389 名前:デフォルトの名無しさん mailto:sage [2009/05/01(金) 18:24:11 ] つGDI+
390 名前:デフォルトの名無しさん mailto:sage [2009/05/02(土) 14:22:24 ] >>385 ちなみにサムネイル生成処理はちゃんと別スレッドでやってる? 画像ファイルが1000超えるような場合のエクスプローラの挙動見れば分かるけど、 非同期でやらないとどれだけ高速化しても厳しいと思うよ
391 名前:デフォルトの名無しさん mailto:sage [2009/05/02(土) 19:20:06 ] そうですね、10個表示されてたらいくつも平行してサムネイルが描画されていってますものね 私もスレッドはやってみようとしかけたのですが、結局ImageListに登録する所あたりで挫けてしまいました スレッドCreateでFileName、サムネイルの大きさを渡してBitMapを返してもらうのか(どうやって?) スレッドの中でImageListにAddするのか ListView.OnDataHintとスレッドがどんなお付き合いにしたらいいのかが分からないのです あ、ちなみに>>389 さんのGDI+は試したらずいぶんと速くなりました
392 名前:デフォルトの名無しさん mailto:sage [2009/05/02(土) 20:16:40 ] CなどのコードをDelphiへ移植する時、Delphiで使えない識別子があった場合はみなさんどうしてますか?
393 名前:デフォルトの名無しさん mailto:sage [2009/05/02(土) 21:58:43 ] comboboxのitemを右クリックしたらポップアップメニューを出したいんだけど、 どうしたら良いですか? ContextPopupにPopupmenu1.Popup(X,Y)ってやっても何も起こらないです。
394 名前:393 mailto:sage [2009/05/02(土) 22:27:06 ] 事故レスです。 レジマネジャーって言うフリーのコンポの バグみたいです。 新規でテストプログラムかいたら出来ました。
395 名前:デフォルトの名無しさん mailto:sage [2009/05/03(日) 19:27:46 ] >>391 実際にスレッド内部からImageList.Add呼んだら問題が起きた?そこまでやったの? とりあえずぐちゃぐちゃになってもいいからやってみないことには問題点も分からないじゃない
396 名前:デフォルトの名無しさん mailto:sage [2009/05/03(日) 22:11:13 ] やってみました。 何度も暴走させながらも(スレッドってまともに動かしたことがないもので)出来ました 目に見えるItemが同時に読み込まれている感がないのでまだまともに出来ている ワケではないのでしょうが取り敢えず正確に表示できて明らかに今までより 表示速度は速くなりました(4000Filesほど読み込ませても数秒でした) ありがとうございました
397 名前:デフォルトの名無しさん mailto:sage [2009/05/03(日) 23:11:33 ] マルチスレッド歴1ヶ月のおいらがわかる事はとりあえず、 ImageList.Addメソッドの呼び出しは最低限、クリティカルセクションなりを用いて排他制御 しなきゃいけなさそうと言う事だけ。 後はわかんない。ぷぎゃ。 CriticalSection.Accuire; try ImageList.Add finally CriticalSection.Release; end;
398 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 00:36:07 ] いや、いらないからw
399 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 01:01:10 ] >>397 だけど、今、具体的にImageListのAddメソッド追ってみたけど、 内部でHandleNeededが呼ばれて、そのHandleNeededでフィールドのFHandleを参照しているから、 下手すると、 procedure TCustomImageList.HandleNeeded; begin if FHandle = 0 then CreateImageList; end; で、CreateImageListに複数のスレッドが同時に突入すると、イメージリストのハンドル が複数作成され、迷子になっちゃわない? ハンドルリークだから、まぁ、そこまで被害拡大しないと思うけど。
400 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 01:12:08 ] ああ、というか、そもそも前提がお互い違うのかもね。 おいらの場合は、サムネイル作成するサブスレッドでImageListのAddメソッド 呼ぶ事を前提にしてた(それで出来るか分からないけど、ぷぎゃ)。 メインスレッドだけで、ImageList.Addメソッド呼ぶなら必要ないと思う。
401 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 01:42:09 ] 勉強のため、勝手にちょっと作ってみたけど、今のおいらのレベルで作るとこんな感じかな。 TThumnailEvent = procedure (Sender: TObject; ABitmap: TBitmap) of object; TThumnailer = class(TThread) private FFileName: string; FSize: TSize; FBitmap: TBitmap; private FOnThumnail: TThumnailEvent; private procedure CallOnThumnailEvent; protected procedure Execute; override; public constructor Create(CreateSuspended: Boolean; AFileName: string; ASize: TSize); public property OnThumnail: TThumnailEvent read FOnThumnail write FOnThumnail; end;
402 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 01:43:02 ] で、実装は { TThumnailer } constructor TThumnailer.Create(CreateSuspended: Boolean; AFileName: string; ASize: TSize); begin FFileName := AFileName; FSize := ASize; FBitmap := TBitmap.Create; inherited Create(CreateSuspended); end; procedure TThumnailer.CallOnThumnailEvent; begin if Assigned(FOnThumnail) then FOnThumnail(Self, FBitmap); end; procedure TThumnailer.Execute; begin // サムネイル作成処理 // ごにょごにょ if Assigned(FOnThumnail) then Synchronize(CallOnThumnailEvent); // VCLのメインスレッドど同期を取る FBitmap.Free; end;
403 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 01:46:47 ] メインのVCLスレッドでは、 procedure TMainForm.Button1Click(Sender: TObject); var Thumnailer: TThumnailer; begin Thumnailer := TThumnailer.Create(True, FileName, Size, Bitmap); Thumnailer.FreeOnTerminate := True; // 自動破棄 Thumnailer.OnThumnail := OnThumnail; Thumnailer.Resume; end; procedure TMainForm.OnThumnail(Sender: TObject; ABitmap: TBitmap); begin if ABitmap <> nil then ImageList.Add(ABitmap); end; とか。ListView.OnDataHintとかは良くわかってないので省略。
404 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 01:47:39 ] Thumnailer := TThumnailer.Create(True, FileName, Size, Bitmap); は Thumnailer := TThumnailer.Create(True, FileName, Size); だった。orz
405 名前:デフォルトの名無しさん mailto:sage [2009/05/04(月) 01:51:34 ] 「こんなクラス名は嫌だ」