指定した画像の次の画像ファイルの読み込み
ファイルは画像ファイルで
フォルダ名が年月
ファイル名は年月+連番という仕組みの中で
例)
C:\image\2505\2505000001.jpg
C:\image\2506\2506000001.jpg
ファイル名を昇順にした時の指定したファイルの
次の画像を読込させたいのです。
FileListBoxを使用して次の様にしてみたのですが、
1ディレクトリでファイルが5万個ぐらいあり、速度が遅いので、
早く表示するにはどうすれば良いかご教示お願いします。
下記は現在選択されているTImageのファイル名をFileListBoxのパスに関連付、
次の画像を探して表示するというものです。
これがディレクトリが変わる毎にApplyFilePathをするのですが、
すごく遅くて、もう少し早い方法はないかな、と思って質問させて頂きました。
宜しくお願い致します。
if FileExists(Image.Picture.GetFileName) = true then begin
FileListBox1.ApplyFilePath(Image.Picture.GetFileName);
//フォルダ内個数を超えた場合
if FileListBox1.Items.Count = Succ(FileListBox1.ItemIndex) then begin
MessageDlg('次の画像が存在しません。', mtInformation,[mbOk], 0);
exit;
end;
FileListBox1.ItemIndex := Succ(FileListBox1.ItemIndex);
Image.Picture.LoadFromFile(FileListBox1.FileName);
label.Caption:=FileListBox1.FileName;
end;
> 1ディレクトリでファイルが5万個ぐらいあり、速度が遅いので、
1つのフォルダに格納するファイルの数を減らす のは、いかがですか?
FileListBoxを使わず、自前でFindFirst/FindNext/FindCloseでファイルを検索し、表示も必要な範囲に絞ってみる、
というのはどうでしょう?
http://docwiki.embarcadero.com/Libraries/XE7/ja/System.SysUtils.FindFirst
FileListBoxが遅いのは、ListBoxとしての表示内容をWindowsの管理下においているから、ということがあります。
例えば、以下のようにファイル名を全部リストアップし、
後から1つずつ見るような感じですかね?
var
iFound : integer;
SearchRec : TSearchRec;
begin
iFound := FindFirst('C:\image\2505\*.jpg', faAnyFile, SearchRec);
while iFound = 0 do begin
ListBox1.Items.Add(SearchRec.Name);
iFound := FindNext(SearchRec);
end;
FindClose(SearchRec);
end;
皆様 素早い回答ありがとうございました。
igy様
ファイルの数を減らしたいのは山々なんですが、元々決まってるところを変えるのは難しくて断念しました。
通りすがり様
>FileListBoxが遅いのは、ListBoxとしての表示内容をWindowsの管理下においているから、ということがあります。
やはりそうなんですね。なんとなくそんな気はしてました。
deldel様
今回配列にディレクトリ全部を入れて
回すほうが早かったのでそのようにしました。
一応できたプログラムが以下です。
もっといいやりようはあるのかもしれませんが。。
問題なく動作しているようなのでこれで行こうかと思います。
XE3でしたので、こちらを参考にしました
http://www.gesource.jp/weblog/?p=5959
uses System.IOUtils, System.Types;
function Show_Next_Image(strFilePath:string):boolean;
var
intCnt:integer;
strFileDir:string;
strFileName:string;
strSearchPattern: string;
Option:TSearchOption;
arrFileNames:TStringDynArray;
begin
result:=false;
//ファイルのディレクトリを取り出す
strFileDir:=IncludeTrailingPathDelimiter(ExtractFilePath(strFilePath));
//ファイル名に一致する検索パターン
strSearchPattern := '*.jpg';
//ディレクトリの列挙モード
Option := TSearchOption.soTopDirectoryOnly; // トップレベル列挙モード
//指定のディレクトリ内のファイルのリスト
arrFileNames := TDirectory.GetFiles(strFileDir,strSearchPattern, Option);
//指定カウント用
intCnt:=0;
//配列ループ
for strFileName in arrFileNames do begin
//現在表示中の画像が最後かどうか
if strFilePath = arrFileNames[High(arrFileNames)] then begin
MessageDlg('次の画像が存在しません。', mtInformation,[mbOk], 0);
exit;
end;
//現在開いているファイル名までループ
try
if strFileName = strFilePath then
Image.Picture.LoadFromFile(arrFileNames[Succ(IntCnt)])
except
on e:Exception do begin
MessageDlg('画像表示中に不具合が発生しました。'+#13#10 +
'[Err] ' +e.Message, mtError,[mbOk], 0);
exit;
end;
end;
Inc(IntCnt);
end;
result:=true;
end;
ツイート | ![]() |