Gtkdialog: A small script for sorting pictures by resolution

interpretive language scripts


Moderator: Forum moderators

Post Reply
User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Gtkdialog: A small script for sorting pictures by resolution

Post 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
Last edited by puppy_apprentice on Sat Jul 22, 2023 7:59 pm, edited 1 time in total.
Carlspur
Posts: 2
Joined: Tue Nov 16, 2021 11:25 pm

Re: A small script for sorting pictures by resolution

Post by Carlspur »

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

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post by puppy_apprentice »

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

picsorg.jpg
picsorg.jpg (73.27 KiB) Viewed 1257 times
picsorg.sh.gz
delete .gz
(2.44 KiB) Downloaded 67 times
User avatar
MochiMoppel
Posts: 1239
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 21 times
Been thanked: 440 times

Re: A small script for sorting pictures by resolution

Post 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
User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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 ;)

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: A small script for sorting pictures by resolution

Post 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
}

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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)
User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: A small script for sorting pictures by resolution

Post 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

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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

Last edited by puppy_apprentice on Tue Dec 07, 2021 8:17 pm, edited 2 times in total.
User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: A small script for sorting pictures by resolution

Post 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

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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.

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: A small script for sorting pictures by resolution

Post 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"

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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.

User avatar
MochiMoppel
Posts: 1239
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 21 times
Been thanked: 440 times

Re: A small script for sorting pictures by resolution

Post 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

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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.

User avatar
MochiMoppel
Posts: 1239
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 21 times
Been thanked: 440 times

Re: A small script for sorting pictures by resolution

Post 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.

Last edited by MochiMoppel on Wed Dec 08, 2021 9:10 am, edited 1 time in total.
User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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.

User avatar
MochiMoppel
Posts: 1239
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 21 times
Been thanked: 440 times

Re: A small script for sorting pictures by resolution

Post 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!

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post 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.

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: A small script for sorting pictures by resolution

Post 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}

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
MochiMoppel
Posts: 1239
Joined: Mon Jun 15, 2020 6:25 am
Location: Japan
Has thanked: 21 times
Been thanked: 440 times

Re: A small script for sorting pictures by resolution

Post 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
User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post by puppy_apprentice »

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

User avatar
misko_2083
Posts: 196
Joined: Wed Dec 09, 2020 11:59 pm
Has thanked: 10 times
Been thanked: 20 times

Re: A small script for sorting pictures by resolution

Post by misko_2083 »

puppy_apprentice wrote: Wed Dec 08, 2021 6:26 pm

if i publish new version

Why not?

Do you want to exit the Circus? The Harsh Truth
https://www.youtube.com/watch?v=ZJwQicZHp_c

User avatar
puppy_apprentice
Posts: 692
Joined: Tue Oct 06, 2020 8:43 pm
Location: land of bigos and schabowy ;)
Has thanked: 5 times
Been thanked: 115 times

Re: A small script for sorting pictures by resolution

Post by puppy_apprentice »

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

Post Reply

Return to “Scripts”