Skip to content

Instantly share code, notes, and snippets.

@ake-persson
Created November 26, 2019 13:30
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ake-persson/ca6d067b561b29cf923817fff6cfa384 to your computer and use it in GitHub Desktop.
Save ake-persson/ca6d067b561b29cf923817fff6cfa384 to your computer and use it in GitHub Desktop.
Resize images
#!/bin/bash
set -eu
error() {
local msg="$1"
echo $msg >&2
exit 1
}
abspath() {
local path="$1"
# Check path is not empty
[ -z "$path" ] && error "Path is empty"
# Check path exist's
[ -e "$path" ] || error "Path doesn't exit: $path"
# Check path is a directory
[ -d "$path" ] || error "Path is not a directory: $path"
cd "$path"
pwd -P
}
resize() {
local file="$1" size="$2" path="$3"
mogrify \
-path "$path" \
-filter Triangle \
-define filter:support=2 \
-thumbnail "$size" \
-unsharp 0.25x0.08+8.3+0.045 \
-dither None \
-posterize 136 \
-quality 82 \
-define jpeg:fancy-upsampling=off \
-define png:compression-filter=5 \
-define png:compression-level=9 \
-define png:compression-strategy=1 \
-define png:exclude-chunk=all \
-interlace none \
-colorspace sRGB \
"$file"
}
SRC_PATH=$(abspath "${1:-}")
DST_PATH=$(abspath "${2:-}")
MAX_SIZE=${3:-}
# Check binaries
which magick &>/dev/null || error "You need to install ImageMagick"
which mogrify &>/dev/null || error "You need to install ImageMagick"
# Check source and destionation is not the same
[ "$SRC_PATH" != "$DST_PATH" ] || error "Source and dest. path can't be the same"
# Check we set max size or use default
[ -z "$MAX_SIZE" ] && MAX_SIZE="1000"
# Find all the images
for file in $(find "$SRC_PATH" -type f -name *.jpg); do
# Create the destination directory
dir=$(dirname $file)
dst_dir=$DST_PATH${dir##$SRC_PATH}
mkdir -p $dst_dir
# Get the size in pixels
size=$(magick identify -format "%w:%h" "$file")
width=${size%%:*}
height=${size##*:}
# Check if this is already correct size
# or if it's portrait or landscape
if [ "$width" -lt "$MAX_SIZE" -a "$height" -lt "$MAX_SIZE" ]; then
echo "SKIP: $file ($width x $height)"
cp -f "$file" "$dst_dir"
elif [ "$width" -gt "$height" ]; then
echo "$file ($width x $height portrait)"
resize "$file" "$MAX_SIZE" "$dst_dir"
else
echo "$file ($width x $height landscape)"
resize "$file" "x$MAX_SIZE" "$dst_dir"
fi
done
@haxcop
Copy link

haxcop commented May 14, 2020

Hi, could you please give me a hint and explain how to use it? keeps telling me the path is empty even when is being specified.
Thanks

@ake-persson
Copy link
Author

ake-persson commented May 14, 2020

You need src and dst.

./scripct src dst

@ake-persson
Copy link
Author

Give me the whole line you're running

@haxcop
Copy link

haxcop commented May 15, 2020

HI Thanks for your reply,
my file structure is
<images/im1/im1.jpg>
then I created a new folder [dst/]
I run ./script.sh <images/im1/im1.jpg> [dst/]
the result output in the shell is
SKIP: /catalog/icecat3/aaoabt0419/aaoabt0419-large.jpg (400 x 400)
and upon reviewing the [dst/] folder I see the image copied in there like If i ran 'cp src dst'

something is wrong here or I'm doing it incorrectly?.

@ake-persson
Copy link
Author

ake-persson commented May 16, 2020

The command takes 3 arguments. ./script.sh [src] [dst] [size]

It will then resize any image that is larger then that size either vertically of horizontally. If you don't specify a size then it will default to 1000 pixels.

If the file is already smaller then it will simply copy it over since it's already smaller then then size we want.

So I downloaded a few pictures from unsplash and created a structure.

$ tree img/
img/
├── test1
│   ├── alicia-petresc-ttjZ2LAbwDs-unsplash.jpg
│   └── angela-bailey-qgYDMG4hU3w-unsplash.jpg
└── test2
    ├── marcelo-cidrack-TvquR9Ye_i4-unsplash.jpg
    └── test3
        ├── cameron-venti-Z8uJ_8PkNpg-unsplash.jpg
        ├── edward-howell-cvVDDgyU-ps-unsplash.jpg
        ├── nathan-dumlao-YLL-mI9OZAg-unsplash.jpg
        └── randy-fath-2o3tAN2Xh-s-unsplash.jpg

Then I downloaded and ran the script.

$ curl https://gist.githubusercontent.com/mickep76/ca6d067b561b29cf923817fff6cfa384/raw/ac49a86a5385bdc3a1bcc12aa8b2e0eed41f9b16/gistfile1.txt >resize.sh
$ chmod +x ./resize.sh
$ mkdir img2
$ ./resize.sh img img2 2000

Then it will resize all pictures to 2000 if they are larger then that horizontally or vertically and we end up with an identical structure in the destionation.

$ tree img2/
img2/
├── test1
│   ├── alicia-petresc-ttjZ2LAbwDs-unsplash.jpg
│   └── angela-bailey-qgYDMG4hU3w-unsplash.jpg
└── test2
    ├── marcelo-cidrack-TvquR9Ye_i4-unsplash.jpg
    └── test3
        ├── cameron-venti-Z8uJ_8PkNpg-unsplash.jpg
        ├── edward-howell-cvVDDgyU-ps-unsplash.jpg
        ├── nathan-dumlao-YLL-mI9OZAg-unsplash.jpg
        └── randy-fath-2o3tAN2Xh-s-unsplash.jpg

3 directories, 7 files

I ran this on Mac OS X using Bash.

So the behaviour you're getting is by design, that it would skip a file of size 400x400 since it's already smaller then the default size of 1000 pixels.

@ake-persson
Copy link
Author

If you want to modify it to always resize just modify the following.

    # Check if this is already correct size
    # or if it's portrait or landscape
#    if [ "$width" -lt "$MAX_SIZE" -a "$height" -lt "$MAX_SIZE" ]; then
#        echo "SKIP: $file ($width x $height)"
#        cp -f "$file" "$dst_dir"
    if [ "$width" -gt "$height" ]; then
        echo "$file ($width x $height portrait)"
        resize "$file" "$MAX_SIZE" "$dst_dir"
    else
        echo "$file ($width x $height landscape)"
        resize "$file" "x$MAX_SIZE" "$dst_dir"
    fi

@haxcop
Copy link

haxcop commented May 18, 2020

Thanks for the detailed reply.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment