午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

大量の画像ファイルから目的のものを選ぶアプリを作りなおしている途中

大量の画像ファイルから目的のものを選ぶアプリを作りなおしている途中

gogowaten.hatenablog.com

これの続き

 

似たような写真撮りすぎてどれを投稿しようか選ぶときに使いたい
この写真が良さそうだけどもっといいのがあるかもってパラパラ見ていて
やっぱりさっきのがいいなって、さっきのはどこーってよくなる
 

f:id:gogowaten:20191024140152p:plain

見た目
左がフォルダの中の画像一覧で、右が一時的に選んだ画像
 

f:id:gogowaten:20191024140204p:plain

エクスプローラなどからファイルかフォルダをドラッグアンドドロップすると
左のパネルに画像が一覧表示される
 

f:id:gogowaten:20191024140215p:plain

目的の画像が見つかったら
左のパネルから右のパネルへドラッグアンドドロップで追加
 

f:id:gogowaten:20191024140226p:plain

操作のほとんどはマウスドラッグ
下に表示されている大きな画像の上でマウスホイールを回すと
画像が切り替わる
 
 
不具合、仕様
選んだ画像パネルに同じ画像をドロップすると重複して登録される
登録した画像はアプリ終了までパネルから削除できない
登録画像を複数選択してのドラッグアンドドロップはできない
大量(3000枚とか)の画像が入ったフォルダや画像をドロップすると
表示まで時間が(2分以上)かかるか途中でエラーになるかも
32ビット版はフルHDの100倍とかの大きな画像(16000x16000ピクセルとか)を開くとエラーで止まる
 

このアプリを作るのに
使ったアプリはVisual Studio Community 2015
OSはWindows 10

参照したところ
 
対応OSはWindows
Windows 10 そのまま動くはず
Windows 8Windows 8.1 動くはず
Windows VistaWindows 7は.NETの新しいのを入れれば動くと思う

ダウンロード先
OneDrive

使ってみた

f:id:gogowaten:20191024140343p:plain

3000枚の中から選んだところ
 
鉢植えトマト(レッドオーレ)C株側枝第1花房

f:id:gogowaten:20191024140356p:plain

Pixtack紫陽花に渡して作ったけど
渡すときに複数同時に渡せないと不便だなあと思った
渡せるようにしたい
 
 
 


 
画像ファイルの読み込み時間

f:id:gogowaten:20191024140408p:plain

画像ファイル700で6秒
画像ファイル数3000枚で1分かかる
しかも途中でキャンセルできない
 
見慣れないエラー?画面

f:id:gogowaten:20191024140422p:plain

3000枚の途中、半分過ぎたあたりかなこの画面が表示された
OK押して続行押したら止まったところから読み込みだしたみたいで
その後は普通に表示された
 
その他

f:id:gogowaten:20191024140431p:plain

画像一覧表示の表示方法変更
左上のボタンを押すと下画面に文字がいっぱい出てくる
もう一回左上のボタンを押すと元の画像表示に戻る
 
いっぱいある文字の画面の下にスクロールして
Viewの項目LargeIconのところを変更すると見た目が変わる
 
SmallIcon

f:id:gogowaten:20191024140442p:plain

SmallIconっていってもアイコンを登録していないから
文字だけが表示される
 

f:id:gogowaten:20191024140452p:plain

Tileは使えそう
View以外もいろいろいじれる
 
 
経緯

f:id:gogowaten:20191024140503p:plain

前回の2画面のアプリがいまいちだなあって別のを作り始めてやっとここまでできた
今回のアプリで縮小した画像を一覧表示するのに使っているコントロールはListView
このListViewってのはスゴイ、3000個の画像を同時に表示させていても遅くなったりしないで普通に動く、スクロールバーもスルスル動く
 
縮小した画像をたくさん表示したくてListViewにたどり着くまで試したのが
FlowLayoutPanelにPictureBoxを並べる、FlowLayoutPanelはアプリのウィンドウの大きさに合わせて自動で整列してくれるのはいいけど遅い、超遅い

f:id:gogowaten:20191024140514p:plain

赤色背景のところがFlowLayoutPanel

次にPictureBoxを自分で普通に並べる、FlowLayoutPanelよりは軽いけど2000個くらい並べると遅い、

f:id:gogowaten:20191024140527p:plain

左の2列の縮小画像一個一個がPictureBox
どちらもアプリ自体が遅くなるんじゃなくてウィンドウズ全体のような、画面の書き換えが間に合ってない感じでマウスカーソルの移動もカクカクになっていた
タスクマネージャーで見ると

f:id:gogowaten:20191024140538p:plain

デスクトップウィンドウマネージャーのCPU占有率が高くなっていた
今使っているCPUは3コアだから33%専有はシングルスレッドだとmax
 
今にして思うとPictureBoxもボタンやラベルと同じコントローラ
そのコントローラを何千個も表示するのは間違った方法だったんだなあって
ボタンが1000個あるアプリは作り方がおかしいってこと
それでもしばらく気づかなくて取った行動が
見えている範囲だけのPictureBoxを表示すればいいんだから
見えていない画面外のPictureBoxはRemove(削除)しておいて
スクロールバー動かして画面内に入ったらその分表示して見えなくなったのを
Removeしようっていう、こうして書いていてもめんどくさいくらいの処理
スクロールバーの位置は今どこなのかとか、ウィンドウの表示幅が変更された時は並び替えしてとか、スクロールした時表示するPictureBoxの個数はいくつでどこからどこまでになるのかとか
こんなにめんどくさいなら難しそうでめんどくさそうで敬遠していたListViewの方がマシなんじゃないかって思いついてListView使ったって流れてきた
実際ListViewはスゴイ、ちょっとめんどくさいけどスゴイ
 
最初の画像読み込みが時間かかるから読み込んでいる途中でも
読み込んだ分だけ表示して操作もできるようにしたいけど難しい
マルチスレッドっぽく動かせばできるみたいなんだけど説明読んでもわかんない
デリゲートってのがさっぱり
 
時間のかかる処理の進行状況を表示する: .NET Tips: C#, VB.NET
 
.NETマルチスレッドプログラミング 1:スレッドの実行と同期 (1/2):CodeZine(コードジン)
 
マルチスレッドで動作する.NETのプログラムサンプル | ラシカル開発記
このへんをもう少し眺めてみる
 
2015年11月7日追記
眺めた結果
BackgroundWorkerの使い方メモ.NET VB、大量の画像ファイルを読み込んでListViewに縮小画像を表示 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
 
続きの記事
大量の画像ファイルから目的のものを選ぶアプリを作りなおしている途中その2 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ