I've got a number of photos, each of which are a different size and resolution. I'd like to make them all square - the resolution isn't critical, and can differ by photo, but each output image must be square in proportion.

I also need to ensure that the original photo is not distorted or skewed in any way - I assume this can be done via adding white space at the bottom of a horizontal rectangular photo (for example), but there could be other ways to achieve this...

Any help would be great!



3 Answers 3


You can use ImageMagick to resize the image and place it in a larger canvas with a white background. If you use Mac or Linux, you can process files in a for loop:

mkdir output
for i in *.jpg ; do
   convert "$i" -resize 4096x4096 -gravity center -background white -extent 4096x4096  "output/${i%.jpg}-processed.jpg"

You can use parallel to process multiple files simultaneously:

mkdir output
for i in *.jpg ; do
   echo convert \"$i\" -resize 4096x4096 -gravity center -background white -extent 4096x4096  \"output/${i%.jpg}-processed.jpg\"
done | parallel

I did something similar in order to create pictures that were of exactly the same dimensions for a html slideshow, even if the original file had been cropped, or was portrait or landscape in orientation. I used gimp and a scheme script to make the process easier as this variation in input size and ratio made the process a pain. I didn't fully automate it though as I was only doing five pictures at a time and I am very much a self taught beginner at coding. Even so this ran to just over a hundred lines of code.
The process was roughly as follows:

  1. If the input image width is greater than the height, scale the image to the target width by original height x (original width / target width). Alternatively target height by original width x (original height / target height).
  2. Resize the canvas to target width by target height with offsets centered.
  3. Flatten and save file.

code listing

;; -*-scheme-*-
;; dmkonlinux 2014
;; resizes files larger than 1024 by 1024 to 1024 pixels on the longest side then applies a black canvas to create a 1024 by 1024 pixel square image for "1024by1024 x.jpg"
;; add ability to resize 1080 by 1435, 75% quality sRGB optomised, progressive, baseline, strip exif for "1080by1435 x.jpg"
;; tested on Ubuntu 17.10 and Gimp 2.8.22

(define (script-fu-dmkonlinux-web-image2    image                       ;define function and parameters in order of SF statements at end ie SF-IMAGE=image SF-DRAWABLE=drawable
(let*   (                                                           ;define variables
    (width (car (gimp-image-width image)))                      ;use start of gimps image width variable
    (height (car (gimp-image-height image)))                    ;use start of gimps image height variable
    (targetwidth)                                                   ;a variable for the target width dependant on option_size
    (targetheight)                                              ;a variable for the target height dependant on option_size
    (gimp-image-undo-group-start image)                     ;start an undo group for the image
    (gimp-context-set-interpolation 2)                          ;sets the interpolation method to (2) cubic
    (gimp-context-set-default-colors)                           ;sets the foreground / backgroud colours to default (black / white)
    (gimp-context-swap-colors)                                  ;swops the foreground / background colours

    (cond   ((= option_size 0) (set! targetwidth 1024)          ;if option_size is 0 (1024x1024) set targetwidth to 1024
                   (set! targetheight 1024))                        ;if option_size is 0 (1024x1024) set targetheight to 1024
        ((= option_size 1) (set! targetwidth 1435)              ;if option_size is 1 (1080x1435) set targetwidth to 1435
                   (set! targetheight 1080))                        ;if option_size is 1 (1080x1435) set targetheight to 1435

    (if (> width height)
        (gimp-image-scale image targetwidth (/ height (/ width targetwidth)))       ;then scale image to width targetwidth by new height (divide height by ratio of width divided by targetwidth)
        (gimp-image-scale image (/ width (/ height targetheight)) targetheight)     ;else scale to...
    (set! width (car (gimp-image-width image)))                 ;reset width and height to new dimensions
    (set! height (car (gimp-image-height image)))
    (gimp-image-resize image targetwidth targetheight (/ (- targetwidth width) 2) (/ (- targetheight height) 2))    ;resize canvas to targetwidth by targetheight with offsets centered
    (gimp-image-flatten image)                          ;flatten image alpha to background colour
    (gimp-image-undo-group-end image)                       ;end an undo group

(let*   (                                       ;define some local variables
    (drawable (car (gimp-image-get-active-drawable image)))             ;drawable has changed so this finds the drawable layer that is needed for file-web-export
    (dir_name)                                  ;define variable dir_name for save proceedure
    (filename)                                  ;define variable filename for save proceedure
    (filenumber adjustment_number)                          ;define variable filenumber for save proceedure abd set to adjustment_number
    (comment "")                                    ;define variable comment for save proceedure

    (cond   ((= option_size 0) (set! filename "1024by1024 ")                                ;if option_size is 0 (1024x1024) then filename = 1024by1024
                   (set! dir_name "Desktop/")                                   ;and dir_name is users desktop
                   (set! comment "resized to 1024x1024"))                           ;and comment is resized to 1024x1024
        ((= option_size 1) (set! filename "1080by1435 ")                                ;if option_size is 1 (1080x1435) then filename = 1080by1435
                   (set! dir_name "Desktop/")                                   ;and dir_name is users desktop
                   (set! comment "resized to 1080x1435"))                           ;and comment is resized to 1080x1435

    (set! filename (string-append dir_name filename (number->string filenumber) ".jpg"))    ;set filename to dir_name + filename + filenumber (number converted to string) + ".jpg"

    (gimp-image-detach-parasite image "gimp-metadata")                  ;lifted from gimp-save-for-web on github these are intended to remove the exif info and file save settings before saving
    (gimp-image-detach-parasite image "exif-data")
    (gimp-image-detach-parasite image "jpeg-settings")

    (gimp-image-set-filename image filename)                        ;set gimps filename to reflect the file as saved
    (file-jpeg-save 1 image drawable filename filename 0.75 0 1 1 comment 0 1 0 0)      ;this proceedure is save as jpeg.  params only used if used NON-INTERACRIVE (0)
)                                               ;   1 : run NON-INTERACTIVE  
                                                ;   image : variable containing image id
                                                ;   drawable : variable containing drawable id
                                                ;   filename : variable containing image filename
                                                ;   raw_filename : variable containing image filename
                                                ;   0.75 : value for quality setting
                                                ;   0 : value for smoothing (off)
                                                ;   1 : value for optimisation (on)
                                                ;   1 : value for progressive (on)
                                                ;   comment : variable containing comment
                                                ;   0 : value for subsampling (chroma quatered)
                                                ;   1 : value for baseline jpeg (on)
                                                ;   0 : value for restart markers (off)
                                                ;   0 : value for dct method (integer)

(gimp-displays-flush)                           ;flush all pending updates of image manipulations to the user interface
(gimp-image-clean-all image)                ;resets dirty count to 0 and allows closing without save dialogue.

(script-fu-register "script-fu-dmkonlinux-web-image2"
_"dmkonlinux web image resize2"
_"scale image to 1024 by 1024 or 1080 by 1435 and add background colour canvas"
"dmkonlinux, 2014"
"Sept 2014"
SF-IMAGE    "Input Image" 0                                                 ;the current image id
SF-DRAWABLE "Input Drawable" 0                                      ;the current drawable id
SF-OPTION   "Size"          '("1024 by 1024" "1080 by 1435")                ;display option box widget with list option 0, option 1
SF-ADJUSTMENT   "File number"       '(1 1 20 1 10 0 SF-SPINNER)         ;display adjustment box widget with lstart value, lower / upper values, step_inc, page_inc, digits after decimal point, type slider or spinner

(script-fu-menu-register "script-fu-dmkonlinux-web-image2"

;(gimp-image-get-filename (gimp-item-get-image item)
;(gimp-image-list) returns number of open images and array of image id's ie (2#(2 1))
;(cadr(gimp-image-list) returns the the first item of the tail of gimp-image-list ie #(2 1)
;(aref(cadr(gimp-image-list)) 0) returns the value at array ref 0 ie 2
;(gimp-get-parasite-list) returns global parasite list ie (1 ("jpeg-save-defaults"))
;(gimp-image-get-parasite-list 1) returns number of parasites and string array of currently attached parasites for image id ie (5 ("jpeg-save-options" "jpeg-settings" "exif-data" "gimp-comment" "gimp-metadata"))
;(gimp-file-save RUN-INTERACTIVE image drawable filename raw_filename) this proceedure calls the save by filetype proceedure

; saved to home/gimp-2.8/scripts
; changed location to dmkonlinux's
; 17/01/2015 added set default colours and swap colours and launch web export window
; 27/08/2017 changed to file-jpeg-save from downloaded c plugin gimp-save-for-web
; 27/08/2017 added 2nd file size for alternative image
; 22/10/2018 little tidy up for photography se answer

This script is very rough and ready, it is heavily commented for my own benefit as it's possibly only the second scheme script I've have (or may ever) write. It should enable anyone to adapt it relatively easily though. It is written on linux ubuntu so the reference for file save directory needs attention for other users and obviously the output file resolution needs to be altered to suit your needs.

  • \$\begingroup\$ Thanks dmkonlinux. This does sound like the type of thing I'm looking for - would you be willing to share your code? \$\endgroup\$
    – Nat Aes
    Commented Oct 22, 2018 at 16:45
  • \$\begingroup\$ @NatAes I've added the code (at the risk of upsetting the off topic police), hope it helps. \$\endgroup\$
    – dmkonlinux
    Commented Oct 23, 2018 at 17:29

There are multiple different ways to do this. The easiest would be to crop the images to make them square ( in Photoshop this can be easily done by giving the crop tool a specified side ratio). But this is the obvious method and I do not think that you want to loose anything of your images.

The way you describe can be achieved in Photoshop by creating a new image in the correct size, with the correct side ratio and the correct background color (i.e. white) and then simply add the photo you want to use in this image and resize it to fit in this new frame. To ensure the original is not disorted you can lock the side ratio with the lock symbol in the toolbar.

If you have to do this for a lot of images and because you are always doing the same steps you could also automate this with photoshop with actions.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.