解像度で画像を並び替える
ファイルの回復が完了し、リカバリ後のタスクスクリプトの助けを借りて画像を復元したら、画像を解像度でソートすると良いでしょう。これにより、撮影した写真、ウェブカメラの画像、またはその他の画像を、解像度が同じ関連画像が多いフォルダにソートできます。
画像に関する情報を収集する
collect-info-about-images.sh
#!/bin/bash
if [ 'XX' != 'XX'"$1" ]; then
if [ -f "$1" ]; then
# mime part start
IsIt=$(file "$1" --mime-type -b);
NeedImageOnly="ItIs_"${IsIt/'/'*/}
if [ "$NeedImageOnly" == "ItIs_image" ] ; then
# mime part end
ImageInfoFEH=($(feh -l "$1"))
IfDamaged=${?}
ImageType=${ImageInfoFEH[9]}
Height=${ImageInfoFEH[11]}
Width=${ImageInfoFEH[10]}
if [ "$IfDamaged" != '0' ]; then
echo "$1" "Damaged" "${IfDamaged}";
fi;
echo "$1"'|'W'|'$Width'|'H'|'$Height'|'Format'|'$ImageType'|'Errors'|'$IfDamaged'|' >> collect-info-about-images.txt
# mime part start
fi
# mime part end
else
echo The « "$1" » is not a valid file name.
fi
else
ScriptsName=${0##*/}
find -type f -exec sh -e "./$ScriptsName" "{}" \;
#find -type f -name "*.jpg" -o -name "*.gif" -o -name "*.png" -exec sh -e "./$ScriptsName" "{}" \;
fi
$IfDamaged 変数は、feh によって返される終了ステータスコードを含みます。
また、pngcheckAUR をインストールして "PNG, JNG, MNG" の整合性をチェックし、および/または jpeginfoAUR をインストールし、$IfDamaged 変数のエラー出力を使用するか、破損したファイルを collect-info-about-images.txt ファイルに追加しないようにスクリプトを変更できます。
pngcheckAUR のチェック結果のサンプル:
./f939799496.png invalid IDAT row-filter type (11) ./f939799496.png private (invalid?) IDAT row-filter type (236) (warning) ./f939799496.png private (invalid?) IDAT row-filter type (231) (warning) ./f939799496.png invalid IDAT row-filter type (49) ./f939799496.png zlib: inflate error = -3 (data error) ERROR: ./f939799496.png OK: ./f218842888.png (532x552, 32-bit RGB+alpha, non-interlaced, 95.8%).
jpeginfoAUR のチェック結果のサンプル:
f62152912.jpg 5678 x 2829 24bit Exif N 11625509 Corrupt JPEG data: 1074 extraneous bytes before marker 0xd9 [WARNING] f124619744.jpg 144 x 119 24bit JFIF N 5813 [OK]
スクリプト内の文字列から必要なデータを抽出するには、sed や gawk などの外部プログラムの代わりに、expressionを使用して、スクリプトの動作を少し高速化することが望ましいです。例えば、
AA="$(jpeginfo -c f62152912.jpg)";
ZZ="${AA/*' [OK]'/}";
if [ 'XX'"$ZZ" == 'XX' ]; then
echo File is good'!!!';
fi
collect-info-about-images.sh スクリプトは、以下のパターンで画像に関するデータを生成します。
画像へのフルパス|幅|サイズ|高さ|サイズ|フォーマット|画像の種類|エラー|feh による終了コード|
サンプル: Images/f269351998.bmp|W|40|H|39|Format|bmp|Errors|0|
Sort images by resolution
This script creates folders based on the resolution. You can set your limitations about how many files should be in each folder and how many sub-directories in a base file type named folder. When limit is reached a new number in the order will be added to a directory name for creation. If you have a really huge amount of files and do not want to overload a single folder with all of them then you can also add your own counters for a new sub-folders after the base destination variable IfExist="${Destination}/, just look out for quotes " to be in the begin and end of a whole destination path. It use to be much more easier to browse folders with a limited amount of images, thumbnails loads much faster and to remember or add to favorite a folder number/name instead of trying to find once more same image in an overloaded folder out of probably thousand images there.
#!/bin/bash
NumberOfBaseDir="0"
SubDirNumber="0"
CountAll="0"
NumDir="0"
echo Creating destination.
Destination="./SortedImages"
echo mkdir -v "${Destination}" -p
echo Created destination with status: $?
echo Your set of limitations.
SDN=50; echo Limit files in a subdir: $SDN
NBD=50; echo Limit subdirs in a file type named destination: $NBD
SourceDataFile="collect-info-about-images.txt"
echo Source file with a necessery data: $SourceDataFile
if [ 'XX' == 'XX'"$SourceDataFile" ] ; then
echo The '$SourceDataFile' variable is empty
exit 1
else
if [ ! -f "$SourceDataFile" ]; then
echo The "$SourceDataFile" file doesn"'"t exist
exit 2
fi;
fi;
echo Populating an array from a file
ArrayFillCount=0;
while read line ; do
tmpWb="${line/|H|*/}";
W="${tmpWb/*W|/}";
tmpHb="${line/|Format|*/}";
H="${tmpHb/*|/}";
#if (( "$W" >= "800" )) && (( "$W" <= "1000" )); then
#if (( "$H" >= "800" )) && (( "$H" <= "1000" )); then
ArrayOfFiles[$ArrayFillCount]="$line";
ArrayFillCount=$((ArrayFillCount+1))
DupLimitKeeper[$W,$H]="0";
#fi;fi;
done < $SourceDataFile;
echo Done with extracting of necessary data about resolutions.
echo Starting loop of restoration
XX=${#ArrayOfFiles[@]}
while [ "${XX}" != "${CountAl}l" ] ; do
preType=${ArrayOfFiles[$CountAll]/*"|Format|"/};
ImageType=${preType/|*/}
preW=${ArrayOfFiles[$CountAll]/*"|W|"/};Width=${preW/|*/};preH=${ArrayOfFiles[$CountAll]/*"|H|"/}
Height=${preH/|*/};
PathToFile=${ArrayOfFiles[$CountAll]/"|"*/}
DupLimitKeeper[Width,Height]=$((DupLimitKeeper[Width,Height]+1));
IfExist="${Destination}/${ImageType}${NumberOfBaseDir}/Resolution_${Width}x${Height}_DirN${SubDirNumber}"
if [ ! -d "$IfExist" ];then
echo mkdir -vp "$IfExist"
NumDir=$((NumDir+1));
fi
## Creating a new numbered file type folders
if [ "${DupLimitKeeper[Width,Height]}" -gt $SDN ]; then
SubDirNumber=$((SubDirNumber+1));
DupLimitKeeper[$Width,$Height]="0";
fi
## Adding a file number
FileNameOnly="${PathToFile##*/}"
NewFileName="N${CountAll}C${FileNameOnly}"
#NewFileName="${FileNameOnly}"
## Creating a new sub-dir when limit of files in a sub-folder is reached
if [ $NumDir -gt $NBD ];then
NumberOfBaseDir=$((NumberOfBaseDir+1));
NumDir="0";
fi
##
if [ -f "${PathToFile}" ];then
echo mv -v "${PathToFile}" "$IfExist/$NewFileName";
# echo cp -v "${PathToFile}" "$IfExist/$NewFileName";
fi
CountAll=$((CountAll+1))
done
echo Total processed files: $CountAll
See also
- sort photos into folders based on EXIF data[リンク切れ 2022-09-23]