Page 1 of 1

Gtkdialog: A small script for sorting pictures by resolution

Posted: Sun Jul 18, 2021 9:00 pm
by puppy_apprentice

I wanted to sort my wallpaper collection by resolution. Maybe it will be useful to someone.
picseg.sh:

Code: Select all

#!/bin/sh
for pic in "$@"
do
	ret=($(imginfo -f "$pic"))
	res=${ret[2]}x${ret[3]}
	if [[ ! -d "$res" ]]
	then
		mkdir "$res"
	fi
	if [[ ! -f "$res/$pic" ]]
	then
		mv "$pic" "$res"
	fi
done

usage:

Code: Select all

picseg.sh *.jpg

Re: A small script for sorting pictures by resolution

Posted: Tue Nov 16, 2021 11:54 pm
by Carlspur

What a neat idea! I look forward to trying it out.


Re: A small script for sorting pictures by resolution

Posted: Mon Dec 06, 2021 6:45 pm
by puppy_apprentice

GUI version with option to add resolution prefix to .jpg files.

picsorg.jpg
picsorg.jpg (73.27 KiB) Viewed 1246 times
picsorg.sh.gz
delete .gz
(2.44 KiB) Downloaded 67 times

Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 4:25 am
by MochiMoppel

@puppy_apprentice imginfo seems to be limited to JPG files. For more versatility you may want to try exiv2 , which supports more formats, notably PNG, also many camera formats like DNG, PEF, RAF et.
AFAIK exiv2 is included in all Puppies.

You also don't need to restrict file extensions. Restricting selection to files with 'jpg' extensions will ignore '*.JPG' or '*.JPEG' files' . Maybe better to let the tool decide what it can handle and what not.

Here a demo how to pick images from a folder, e.g. /root/my_images. Let's assume that this folder contains all sorts of image files and maybe even text files. The code will list image files and their dimensions as far as exiv2 is able to retrieve this information. File extensions are irrelevant. Even image files with no or wrong extensions are supported.

Code: Select all

for f in /root/my_images/* ;do
	res=$(exiv2 "$f" 2>/dev/null  | sed  -n '/Image size/ s/[^0-9x]*//gp')
	if [ $res ] ;then
		echo "$f has resolution of $res"  
	fi
done

Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 11:45 am
by puppy_apprentice

First, I wanted to apply your progressbar idea to the main window. And yes, currently this application only works with .jpg files (I always forget that the Linux filesystem is case-sensitive).

Thanks for the rest of the advices, my Sensei.
Let the cherry trees in your orchard bloom all year round and bear delicious fruits.
Arigato ;)


Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 2:49 pm
by misko_2083
puppy_apprentice wrote: Mon Dec 06, 2021 6:45 pm

GUI version with option to add resolution prefix to .jpg files.

Not yet ready for production.
Here is a couple of notes for the student:

Code: Select all

#!/bin/sh   # Is it suppose to be POSIX compliant? There are Bashisms
addresprefix() {
	if [[ $SOURCE && $DESTINATION ]]   # what if filenames contain spaces or start with a hypen
	then
		amount=$(ls $SOURCE/*.jpg | wc -l)     # again spaces in filenames and hypen, wc -l also counts newlines in filenames 
		i=1
		k=1   # what's this?
		for pic in $(ls $SOURCE/*.jpg)   # spaces, hypens in filename...why ls?    for pic in "$SOURCE"/*.jpg
		do
			ret_array=($(imginfo -f "$pic"))
			res=${ret_array[2]}x${ret_array[3]}
			if [[ ! -f "$DESTINATION/$res-${pic##*/}" ]]
			then
				mv "$pic" "$DESTINATION/$res-${pic##*/}"   # what if filename starts with a hypen?
			fi
			echo -e "$(( 100 * i / amount ))\nProcessing file: $i/$amount"
			(( i++ ))
		done
		sleep 2
		echo  -e "0\nWaiting for action..."
	else
		echo  -e "0\nChoose Source and Destination directories!"
	fi
}

Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 3:06 pm
by puppy_apprentice

Thanks. My all files/directories etc. doesn't contain spaces, hyphens and other characters and my files have always extensions in lower case. So for me it works. Btw. gtkdialog variables like $SOURCE are printed in console like this

Code: Select all

SOURCE="some/path"

So it contain quotes already or not?

wc -l also counts newlines in filenames

Don't have any files with newline, especially downloaded from internet. Why use newline in filenames?

Ok i found option:

Code: Select all

ls -1q | wc -l

but stack give this option:

Code: Select all

shopt -s nullglob; files=(*.jpg); echo ${#files[@]}

or

Code: Select all

count() { echo $#; }
amount=$(count *.jpg)

Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 4:23 pm
by misko_2083
puppy_apprentice wrote: Tue Dec 07, 2021 3:06 pm

Ok i found option:

Code: Select all

ls -1q | wc -l

but stack give this option:

Code: Select all

shopt -s nullglob; files=(*.jpg); echo ${#files[@]}

or

Code: Select all

count() { echo $#; }
amount=$(count *.jpg)

It happens that sometimes files have newlines.
Something like this to include jpg, png, gif with capital letters too.

Code: Select all

#!/bin/bash
DIR="$HOME/Преузимања"

shopt -s nullglob
set -- "$DIR"/*.[jJ][pP][gG] "$DIR"/*.[bB][mM][pP] "$DIR"/*.[pP][nN][gG] "$DIR"/*.[gG][iI][fF]
shopt -u nullglob

NUM=$#
printf "%s\n" "Found $NUM files"

for picture
do
	printf -- "%s\n" "$picture"
	# do something here with the picture
	# mv -- "$picture" "$DESTINATION/$res-${picture##*/}"
done

Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 4:46 pm
by puppy_apprentice

Ok. thanks @misko_2083 for tips.
@MochiMoppel
I don't like sed to much, i like bash arrays way:

Code: Select all

for pic in "$@"
do
	ret=($(exiv2 $pic 2>/dev/nul | grep "Image size"))
	res=${ret[3]}x${ret[5]}
	echo $res
done

And i don't care about POSIX it is tool for ordinary Puppy.
Rox New/Script adds sh shebang and it is symlinked to bash.

What other linuxes (like FatDog or Wee) from this forum use shells?

Edit: changed 1f609.png > $pic


Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 7:46 pm
by misko_2083
puppy_apprentice wrote: Tue Dec 07, 2021 4:46 pm

Ok. thanks @misko_2083 for tips.
@MochiMoppel
I don't like sed to much, i like bash arrays way:

Code: Select all

for pic in "$@"
do
	ret=($(exiv2 1f609.png 2>/dev/nul | grep "Image size"))
	res=${ret[3]}x${ret[5]}
	echo $res
done

Bash rematch is also an option

Code: Select all

for pic in "$@"
do
	ret="$(exiv2 -- "$pic" 2>/dev/null)"
	re='Image[[:blank:]]size[[:blank:]]*:[[:blank:]]([[:digit:]]*)[[:blank:]]x[[:blank:]]([[:digit:]]*)$'
	[[ "$ret" =~ $re ]] && echo "${BASH_REMATCH[1]}x${BASH_REMATCH[2]}"
done

Without grep and array. ;)
-----------------------------------------------
Without nullglob, let me see. by POSIX the match term is printed if there is no match.
So we have to check the file
[ -e "$pic" ] || continue

Code: Select all

for pic in "/home/misko/Преузимања"/*.{[jJ][pP][gG],[bB][mM][pP],[pP][nN][gG],[gG][iI][fF]}; do
	[ -e "$pic" ] || continue
	printf -- "%s\n" "$pic"
done

Or with -f
[ -f "$pic" ] || continue


Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 8:09 pm
by puppy_apprentice

Ok i wil check your tips.
I have pictures sometimes mixed with other files in one directory. So i need catch only picture files and find amount of them to count proper % for progressbar. My script is doing this but only for ".jpg" so far.


Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 8:35 pm
by misko_2083
puppy_apprentice wrote: Tue Dec 07, 2021 8:09 pm

Ok i wil check your tips.
I have pictures sometimes mixed with other files in one directory. So i need catch only picture files and find amount of them to count proper % for progressbar. My script is doing this but only for ".jpg" so far.

jpg, jpeg, bmp, gif and all possible combinations of big and small letters in file extensions.

Code: Select all

i=0
for pic in "/root/apprentice_selfies"/*.{[jJ][pP][gG],[jJ][pP][eE][gG],[bB][mM][pP],[pP][nN][gG],[gG][iI][fF]}; do
	[ -e "$pic" ] || continue
	let i=$i+1
	printf -- "%d   %s\n" "$i" "$pic"
done
echo "Total number of photo selfies: $i"

Re: A small script for sorting pictures by resolution

Posted: Tue Dec 07, 2021 9:48 pm
by puppy_apprentice

I need one without for loop.

This one liner is shorter.

Code: Select all

amount=$(ls -1qb "$SOURCE"/*.gif "$SOURCE"/*.png "$SOURCE"/*.GIF "$SOURCE"/*.PNG 2>/dev/nul | wc -l)

This is improved (should be ok?):

Code: Select all

mask="\.gif$\|\.png$"
source="some/path"
amount=$(ls "$source" | grep -ci "$mask")
echo $amount

Your earlier code is without loop to:

Code: Select all

shopt -s nullglob
set -- "$DIR"/*.[jJ][pP][gG] "$DIR"/*.[bB][mM][pP] "$DIR"/*.[pP][nN][gG] "$DIR"/*.[gG][iI][fF]
shopt -u nullglob

NUM=$#
printf "%s\n" "Found $NUM files"

Still i don't want to take on account filenames with newlines. Newer downloaded one from internet and my phone/camera don't create such a filenames.


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 1:04 am
by MochiMoppel
puppy_apprentice wrote: Tue Dec 07, 2021 9:48 pm

I need one without for loop.

This one liner is shorter.

Code: Select all

amount=$(ls -1qb "$SOURCE"/*.gif "$SOURCE"/*.png "$SOURCE"/*.GIF "$SOURCE"/*.PNG 2>/dev/nul | wc -l)

Not sure why you need -1qb
This one is even shorter. Would also match *.PnG or *.giF :)

Code: Select all

shopt -s nocaseglob
amount=$(ls -1 "$SOURCE"/*.{jpg,jpeg,png,bmp,gif} 2>/dev/null | wc -l)

nocaseglob makes the match case insensitive


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 7:38 am
by puppy_apprentice
MochiMoppel wrote: Wed Dec 08, 2021 1:04 am

Not sure why you need -1qb

To escape some stuff, i've suggested those newlines in filenames, but didn't checked this.

MochiMoppel wrote: Wed Dec 08, 2021 1:04 am

This one is even shorter. Would also match *.PnG or *.giF :)

Code: Select all

shopt -s nocaseglob
amount=$(ls -1 "$SOURCE"/*.{jpg,jpeg,png,bmp,gif} 2>/dev/null | wc -l)

nocaseglob makes the match case insensitive

I've tried this {*.png,*.gif} and didn't works maybe i have used ; instead of , i don't remember.

Again thanks MochiMoppel-san

EDIT: I use extensions (and directory names) in one case, because once I copied the 'TEMP' and 'temp' directory from linux to my flash drive (fat) messed up files.


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 8:24 am
by MochiMoppel
puppy_apprentice wrote: Wed Dec 08, 2021 7:38 am

I've tried this {*.png,*.gif} and didn't works

Of course it doesn't work. That's not what I posted!

[EDIT] code contains unnecessary repetitions but should work.


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 8:32 am
by puppy_apprentice

Code: Select all

ls {*.png,*.gif}

works for lower cases
earlier i've used this i think:

Code: Select all

ls {*.png;*.gif}
or
ls {*.png\|*.gif} like in grep

and get error.
i was writing about wrong globing sequence.


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 9:21 am
by MochiMoppel
puppy_apprentice wrote: Wed Dec 08, 2021 8:32 am

Code: Select all

ls {*.png,*.gif}

works for lower cases

In your previous post you claimed that it does not work. So it's yes or no? When you claim that something does not work please post the complete command you used and not just a fraction.
Did you try what I proposed?

earlier i've used this i think:

Forget it!


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 9:57 am
by puppy_apprentice

I've said:

I've tried this {*.png,*.gif} and didn't works maybe i have used ; instead of , i don't remember.

Only this to test ls (week or more ago):

Code: Select all

ls {*.png,*.gif}

I've didn't comment your whole code.
And i've used semicolon i've checked in bash history. I don't know why i didn't try coma.
If you misunderstood me, sorry.


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 10:54 am
by misko_2083
MochiMoppel wrote: Wed Dec 08, 2021 1:04 am

This one is even shorter. Would also match *.PnG or *.giF :)

Code: Select all

shopt -s nocaseglob
ls -1 "$SOURCE"/*.{jpg,jpeg,png,bmp,gif} 2>/dev/null | wc -l

nocaseglob makes the match case insensitive

Short, still counts newlines in filenames.
This works with nullglob

Code: Select all

shopt -s nullglob nocaseglob
printf 'x%.0s' "$SOURCE"/*.{jpg,jpeg,png,bmp,gif} 2>/dev/null | wc -c

Prints 'x' and zero characters from filename string then counts the character.
Edit....Oh wait, printf can declare a variable, in that case there is no need for wc.

Code: Select all

shopt -s nullglob nocaseglob
printf -v VAR 'x%.0s' "$SOURCE"/*.{jpg,jpeg,png,bmp,gif}
echo ${#VAR}

Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 1:52 pm
by MochiMoppel
puppy_apprentice wrote: Tue Dec 07, 2021 3:06 pm

but stack give this option:

Code: Select all

shopt -s nullglob; files=(*.jpg); echo ${#files[@]}

What was wrong with that?
Extremely short, no ls, no wc, no sed. Uses your beloved arrays, supports odd filesnames with newlines and should keep everybody happy.

Code: Select all

shopt -s nullglob nocaseglob
files=("$SOURCE"/*.{jpg,jpeg,png,bmp,gif})
num=${#files[@]}
echo "found $num image files"
for pic in "${files[@]}"
do
	ret=($(exiv2 "$pic" 2>/dev/null | grep "Image size"))
	res=${ret[3]}x${ret[5]}
	echo "file $pic has resolution of $res"
done

Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 6:26 pm
by puppy_apprentice

I'm so happy with all snippets, that if i publish new version i make a appendix with them.


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 7:16 pm
by misko_2083
puppy_apprentice wrote: Wed Dec 08, 2021 6:26 pm

if i publish new version

Why not?


Re: A small script for sorting pictures by resolution

Posted: Wed Dec 08, 2021 7:22 pm
by puppy_apprentice

I was mean when.
Currently i'm adding new apps to Java thread.