PowerShellでスクリーンセーバー用画像ピックアップ

#はじめに
プライベートですが、FireTVStickを導入しています。
TVでAmazonPrimeビデオが見れるようになるアレですね。
FireTVStickはAmazonDrive上の画像からスライドショーを表示できるんです。
スクリーンセーバーとしても設定できるので目の保養としていい感じです。

ところでTumblrっていいですよね（唐突）
dashboardは自分の好きなものストリームなので無限に見れますし、
自分のblogは好きなものの集合体なのでコレクションとしての価値が大きいです。
そんなTumblrの画像群から、スクリーンセーバー向けの画像のピックアップを行いたいとします。

要件としては以下

- jpgかpngであること
GifファイルはFireTVStickのスライドショーでは動きませんでした。

- 横長の画像で、かつ縦幅の大きいものを優先すること。
画面に映したときに見栄えがいいです。
細長い画像だとあまり美しくないので…

- ファイルサイズの大きいものを優先すること
これも見栄え重視。

対象画像は事前にスクレイピングされているものとします。
ファイル形式もサイズもへったくれもなく1フォルダに入れておきます。

#参考資料様
[画像の仕分けスクリプトをPowerShellで書き直す](https://qiita.com/iwase10moya/items/49f3f43ce73ecbdbbfce)
親元です。私は二番煎じです。
こちらではファイルのプロパティを取得してどうこうされていましたが、
「nnn ピクセル」のString型を整数型に直せず、わかっているやり方に変更。
この部分は「わからなかった部分」として記事末尾に記載しています。

#環境
-Windows10
-PowerShell

#テスト
諸般の事情によりテスト的なものを作成してから持ち込みました。
ランダム画像群を生成してそれに対してスクリプトを実行します。

```powershell:makerandomfile.ps1
#Tumble2Amdrのためのランダムファイル群作成
$path = "C:\Workspace\picturetest"
Add-Type -AssemblyName System.Drawing
foreach($i in @(1..100)){
    $width = Get-Random -Minimum 160 -Maximum 640
    $height = Get-Random -Minimum 160 -Maximum 640
    $image= New-Object System.Drawing.Bitmap($width,$height)
    $image.Save($path+"\jpg_"+$i+".jpg",[System.Drawing.Imaging.ImageFormat]::Jpeg)
    $image.Dispose()
}
foreach($i in @(1..100)){
    $width = Get-Random -Minimum 160 -Maximum 640
    $height = Get-Random -Minimum 160 -Maximum 640
    $image= New-Object System.Drawing.Bitmap($width,$height)
    $image.Save($path+"\gif_"+$i+".gif",[System.Drawing.Imaging.ImageFormat]::gif)
    $image.Dispose()
}
foreach($i in @(1..100)){
    $width = Get-Random -Minimum 160 -Maximum 640
    $height = Get-Random -Minimum 160 -Maximum 640
    $image= New-Object System.Drawing.Bitmap($width,$height)
    $image.Save($path+"\png_"+$i+".png",[System.Drawing.Imaging.ImageFormat]::png)
    $image.Dispose()
}
```
で、これを実行すると…

```powershell:実行結果
PS C:\Workspace\picturetest\item> Get-ChildItem


    ディレクトリ: C:\Workspace\picturetest\item


Mode                LastWriteTime         Length Name                                                                                            
----                -------------         ------ ----                                                                                            
-a----       2018/09/07      8:21           1297 gif_1.gif                                                                                       
-a----       2018/09/07      8:21           1749 gif_10.gif                                                                                      
-a----       2018/09/07      8:21           1413 gif_100.gif                                                                                     
-a----       2018/09/07      8:21           1564 gif_11.gif                                                                                      
-a----       2018/09/07      8:21           1811 gif_12.gif                                                                                      
            （中略）                                                                                 
-a----       2018/09/07      8:21            646 png_95.png                                                                                      
-a----       2018/09/07      8:21           1029 png_96.png                                                                                      
-a----       2018/09/07      8:21            507 png_97.png                                                                                      
-a----       2018/09/07      8:21            651 png_98.png                                                                                      
-a----       2018/09/07      8:21            971 png_99.png     
```
さまざまな画像サイズのファイル群が作成されました。

#ソースコード
本題はこっち。

```powershell:Tumble2Amdr.ps1
# Tumblrの画像群からスクリーンセーバー向けの画像をピックアップ

#画像を扱えるようにする
Add-Type -AssemblyName System.Drawing

#参考値
$ABSOLUTERATIO = 0.5625 #16:9のアス比
$BAND = [math]::round($ABSOLUTERATIO/4,4) 

$filepath = "C:\Workspace\picturetest\item"
$resultpath = "C:\Workspace\picturetest\Result"
$list = Get-ChildItem $filepath

#ファイルの抽出
$pickups = foreach($file in $list){
    if(($file.Extension -eq ".jpg") -or ($file.Extension -eq ".png")){
        #画像読み込み
        $image = [System.Drawing.Image]::FromFile($file.FullName) #画像を読み込む
        $width = $image.Width
        $height = $image.Height
        $image.Dispose()
        
        #下ごしらえ
        if($width -ge $height){
            $ratio = [math]::round($height/$width,4) #画像のアス比
            if(($ratio -ge $ABSOLUTERATIO-$BAND)){ # 許容アス比、これより細い画像は弾く
                [PSCustomObject]@{
                    Fullname = $file.FullName
                    Length = $file.Length
                    Width = $width
                    Height = $height
                }
            }
        }
    }
}

$annoited_list = $pickups | Sort-Object -Descending Width,Height,Length | Select-Object -First 50
$annoited_list|Export-Csv $resultpath"\result.csv" #結果のCSV出力

#ファイルのコピー
foreach($movefile in $annoited_list){
    Copy-Item -Path (($movefile).Fullname) -destination $resultpath
}
```
[Excelizeの時](https://qiita.com/takaaki3110/items/f1e35596520280fc34b6)の画像ノウハウで画像サイズだけ取得してリリース。
適宜条件で弾いてから、リストに入れて並べなおして上位をピックアップ。
アス比閾値を設定して条件に加えることで、クソ細い画像を排除している。


#出力

```powershell:出力結果


    ディレクトリ: C:\Workspace\picturetest\Result


Mode                LastWriteTime         Length Name                                                                                            
----                -------------         ------ ----                                                                                            
-a----       2018/09/07      8:21           5775 jpg_100.jpg                                                                                     
-a----       2018/09/07      8:21           5379 jpg_11.jpg                                                                                      
-a----       2018/09/07      8:21           4211 jpg_12.jpg                                                                                      
-a----       2018/09/07      8:21           4947 jpg_15.jpg                                                                                      
-a----       2018/09/07      8:21           3515 jpg_18.jpg                                                                                      
-a----       2018/09/07      8:21           3187 jpg_19.jpg                                                                                      
-a----       2018/09/07      8:21           5587 jpg_21.jpg                                                                                      
-a----       2018/09/07      8:21           3059 jpg_39.jpg                                                                                      
-a----       2018/09/07      8:21           4427 jpg_48.jpg                                                                                      
-a----       2018/09/07      8:21           5747 jpg_5.jpg                                                                                       
-a----       2018/09/07      8:21           3727 jpg_51.jpg                                                                                      
-a----       2018/09/07      8:21           6099 jpg_56.jpg                                                                                      
-a----       2018/09/07      8:21           2939 jpg_59.jpg                                                                                      
-a----       2018/09/07      8:21           5659 jpg_62.jpg                                                                                      
-a----       2018/09/07      8:21           4427 jpg_66.jpg                                                                                      
-a----       2018/09/07      8:21           4527 jpg_71.jpg                                                                                      
-a----       2018/09/07      8:21           4059 jpg_72.jpg                                                                                      
-a----       2018/09/07      8:21           4147 jpg_74.jpg                                                                                      
-a----       2018/09/07      8:21           3483 jpg_76.jpg                                                                                      
-a----       2018/09/07      8:21           3507 jpg_78.jpg                                                                                      
-a----       2018/09/07      8:21           2611 jpg_8.jpg                                                                                       
-a----       2018/09/07      8:21           3003 jpg_80.jpg                                                                                      
-a----       2018/09/07      8:21           3291 jpg_81.jpg                                                                                      
-a----       2018/09/07      8:21            685 png_100.png                                                                                     
-a----       2018/09/07      8:21            556 png_12.png                                                                                      
-a----       2018/09/07      8:21           1161 png_19.png                                                                                      
-a----       2018/09/07      8:21            757 png_2.png                                                                                       
-a----       2018/09/07      8:21            641 png_20.png                                                                                      
-a----       2018/09/07      8:21           1028 png_21.png                                                                                      
-a----       2018/09/07      8:21           1064 png_26.png                                                                                      
-a----       2018/09/07      8:21            906 png_27.png                                                                                      
-a----       2018/09/07      8:21           1187 png_33.png                                                                                      
-a----       2018/09/07      8:21            997 png_34.png                                                                                      
-a----       2018/09/07      8:21           1217 png_39.png                                                                                      
-a----       2018/09/07      8:21            645 png_4.png                                                                                       
-a----       2018/09/07      8:21            705 png_42.png                                                                                      
-a----       2018/09/07      8:21            898 png_5.png                                                                                       
-a----       2018/09/07      8:21           1292 png_51.png                                                                                      
-a----       2018/09/07      8:21           1527 png_52.png                                                                                      
-a----       2018/09/07      8:21           1260 png_55.png                                                                                      
-a----       2018/09/07      8:21            741 png_60.png                                                                                      
-a----       2018/09/07      8:21            547 png_62.png                                                                                      
-a----       2018/09/07      8:21            631 png_72.png                                                                                      
-a----       2018/09/07      8:21            831 png_75.png                                                                                      
-a----       2018/09/07      8:21            990 png_8.png                                                                                       
-a----       2018/09/07      8:21           1247 png_84.png                                                                                      
-a----       2018/09/07      8:21            901 png_85.png                                                                                      
-a----       2018/09/07      8:21            610 png_93.png                                                                                      
-a----       2018/09/07      8:21            646 png_95.png                                                                                      
-a----       2018/09/07      8:21            971 png_99.png                                                                                      
-a----       2018/09/07      8:24           3226 result.csv                                                                                      
```
![result.png](https://qiita-image-store.s3.amazonaws.com/0/276779/c4a1ea7e-21ea-7409-3f52-47f2133c5b53.png)

![jpg_100.png](https://qiita-image-store.s3.amazonaws.com/0/276779/c25a73b3-72e1-e26c-3bbf-19ae81ded54b.png)
無事ピックアップされたようです。

#わからなかった部分
ここからは親元を参考に試したけどうまくいかなかった部分です。
ファイルのプロパティから画像サイズ自体は取得できそうだったんです。

```powershell:get-option.ps1
#プロパティから対象を探し出す
$path = "C:\Workspace\item"
$list = ls $path *_1.*
# プロパティ取得の準備
# shellの機能を使えるようにする。多分GetDetailsOfのため。
$shell = New-Object -ComObject Shell.Application
# $folderに$pathのフォルダーオブジェクトを代入
$folder = $shell.NameSpace($path)
#ファイルの抽出
$object = $folder.ParseName($file.Name) #オプションを取得できるようにする

#プロパティの抽出
$pickups = foreach($file in $list){
    $object = $folder.ParseName($file.Name) #オプションを取得できるようにする
    Write-Host $file.Name #見やすくするため
    @(1..200)|%{
        $detail = $Folder.GetDetailsOf($object,$_)
        #if($detail -ne ""){
            Write-Host $_`t $detail`t $detail.GetType()
        #}
    }
    Write-Host `r`n`r`n #見やすくするため
}
```
拡張子によってプロパティの内容と位置が変わらないか一応確認しています。

```powershell:結果
PS C:\Workspace> C:\Workspace\get-option.ps1
gif_1.gif
1	 1.25 KB	 System.String
2	 GIF ファイル	 System.String
3	 2018/09/07 9:00	 System.String
4	 2018/09/07 9:00	 System.String
5	 2018/09/07 9:00	 System.String
6	 A	 System.String
7	 	 System.String
8	 オフラインで利用可能	 System.String
9	 イメージ	 System.String
10	 TC\1501275	 System.String
11	 ピクチャ	 System.String
12	 	 System.String
（中略）
168	 	 System.String
169	 8	 System.String
170	 ‎96 dpi	 System.String
171	 ‎162 ピクセル	 System.String
172	 ‎96 dpi	 System.String
173	 ‎495 ピクセル	 System.String
174	 	 System.String
175	 	 System.String
176	 	 System.String
177	 	 System.String
178	 	 System.String
179	 	 System.String
180	 	 System.String
181	 	 System.String
182	 いいえ	 System.String
183	 	 System.String
184	 	 System.String
185	 item	 System.String
186	 C:\Workspace\item	 System.String
187	 item (C:\Workspace)	 System.String
188	 	 System.String
189	 C:\Workspace\item\gif_1.gif	 System.String
190	 	 System.String
191	 GIF ファイル	 System.String
192	 	 System.String
（中略）
289	 	 System.String
290	 非共有	 System.String
291	 利用可能	 System.String
292	 	 System.String
（中略）
499	 	 System.String
500	 	 System.String
（後略）
```
結論からするとどのファイルでもでも171番と173番が幅と高さでした。
ファイルのプロパティは291番が最後っぽいけど他のファイルだと変わるかも。

```powershell
PS C:\Workspace> $width = $folder.GetDetailsOf($object,171)

PS C:\Workspace> $width
‎156 ピクセル

PS C:\Workspace> $width.GetType()

IsPublic IsSerial Name                                     BaseType                                                                              
-------- -------- ----                                     --------                                                                              
True     True     String                                   System.Object     
```
まぁわかる。ピクセル入ってるもんな。

```powershell
PS C:\Workspace> $a=$width.Split()[0]

PS C:\Workspace> $a
‎156

PS C:\Workspace> $a.GetType()

IsPublic IsSerial Name                                     BaseType                                                                              
-------- -------- ----                                     --------                                                                              
True     True     String                                   System.Object
```
そうなるんか。数字だけなら整数型に戻るわけではないのね。

```powershell
PS C:\Workspace> $b = [int]$a
値 "‎156" を型 "System.Int32" に変換できません。エラー: "入力文字列の形式が正しくありません。"
発生場所 行:1 文字:1
+ $b = [int]$a
+ ~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) []、RuntimeException
    + FullyQualifiedErrorId : InvalidCastFromStringToInteger
```
うーん…？
数字だけだけど直ってはくれんのか？

#おわりに
実環境では約30000枚の画像から1000枚ちょいをピックアップします。
その後スクリーンセーバーにふさわしくない画像達を手動で弾きました。
あとはresultフォルダをAmazonDriveと同期してFireTVStickで設定すればOKです。

なおピックアップの結果はほとんどがアニメのキャプになりました。
Duh...

[Takaaki-3110@Tumblr](http://takaaki-3110.tumblr.com)