1

Is there any simple way to autocrop/autoshrink a square image in GIMP, but without changing aspect ratio? Basically the autoshrinking would stop once it's no longer possible to maintain height and width equality.

I've been using this with imagemagick and powershell:

convert $files[$i].Name -set option:size '%[fx:max(w,h)]x%[fx:max(w,h)]' 
\ xc:none +swap -gravity center -composite $outfile

Preferably would like to do this with scheme/script-fu.

1

2 Answers 2

1
  • Duplicate layer
  • Autocrop copy
  • Figure out the size and offsets of a potential square crop of the layer from the cropped width, height and offsets.
  • remove copy
  • crop the original layer using gimp-layer-resize

Something like this:

# -*- coding: utf-8 -*-
#!/usr/bin/env python

import os, sys
from gimpfu import *

def squareCrop(image,layer):
    pdb.gimp_image_undo_group_start(image)

    try:
        x0,y0=layer.offsets

        # get size and offsets of fully autocropped layer
        copy=layer.copy()
        image.add_layer(copy)
        pdb.plug_in_autocrop_layer(image,layer)
        xC,yC=copy.offsets
        hC,wC=copy.height,copy.width
        image.remove_layer(copy)

        # determine padding direction
        topBottomPad=wC > hC
        pad=abs(hC-wC)/2

        # determine size and offsets for resize
        xOff,yOff=(x0-xC,y0+pad-yC) if topBottomPad else (x0+pad-xC,y0-yC)
        w,h=(wC,wC) if topBottomPad else (hC,hC)

        layer.resize(w,h,xOff,yOff)

    except Exception as e:
        print e.args[0]
        pdb.gimp_message(e.args[0])

    pdb.gimp_image_undo_group_end(image)

### Registrations
whoiam='\n'+os.path.abspath(sys.argv[0])

register(
    'square-crop',
    'Square crop'+whoiam,
    'Square crop',
    'Ofnuts','Ofnuts','2016',
    'Square crop...',
    "RGB*",
    [
        (PF_IMAGE, "image", "Input image", None),
        (PF_DRAWABLE, "drawable", "Input drawable", None),
    ],
    [],
    squareCrop,
    menu="<Image>/Layer/Transform",
)

main()

Note you cannot crop that way if you are too close to a border, because the padding would extend beyond the canvas limits (something which isn't checked by the code above)

11
  • maybe this is dumb, but I'm not sure how to get this to work. I've tried placing it in the same directory where my scheme scripts are but it doesn't show up Commented Aug 11, 2016 at 12:52
  • This is Python, so technically it is a plug-in, not a script, and so should be in the plug-ins directory instead of the scripts one (and should have the executable flag on Linux and OSX).
    – xenoid
    Commented Aug 11, 2016 at 20:48
  • I actually did try it there, no luck. I do have another python script in that folder that does show up, however. Commented Aug 12, 2016 at 15:53
  • Your copy/paste likely lost/added a few spaces and Python is very sensitive to this... Get the file from there and retry.
    – xenoid
    Commented Aug 13, 2016 at 8:54
  • still no luck. is there a python equivalent of the script-fu console? might be able to debug more easily from there. otherwise I'll try to reverse engineer it into scheme Commented Aug 21, 2016 at 5:51
-1

Here's my solution:

(define (square image drawable)
    (gimp-image-undo-group-start image)
    (gimp-context-push)
    (plug-in-autocrop 1 image drawable)
    (let* (
        (width (car (gimp-image-width image)))
        (height (car (gimp-image-height image)))
        (newWidth width)
        (newHeight height)
        (layer (vector-ref (cadr (gimp-image-get-layers image)) 0))
    )

        (if (< width height)
            (set! newWidth height)
        )
        (if (> width height)
            (set! newHeight width)
        )

        (gimp-image-resize image newWidth newHeight (/ (- newWidth width) 2) (/ (- newHeight height) 2))
        (gimp-layer-resize-to-image-size layer)

        (gimp-image-clean-all image)
        (gimp-context-pop)
        (gimp-image-undo-group-end image)
        (gimp-displays-flush)

        (list newWidth newHeight)
    )
)
(script-fu-register
    "square"
    "<Image>/Tools/Square"
    ""
    "Matthew Morrone"
    "Uncopyright 2016 Matthew Morrone"
    "27 September 2016"
    "*"
    SF-IMAGE "Input Image" 0
    SF-DRAWABLE "Input Drawable" 0
)
3
  • Well, is that an answer or is that a new question or should it better be an edit of the original question? Please see that the space for answers should only be used for real answers ...
    – Mensch
    Commented Sep 27, 2016 at 16:35
  • No, this is an answer, just wanted to point out that it that there may be a better way to do this. Commented Sep 27, 2016 at 17:03
  • You could describe what it does - or is supposed to do. Without looking too hard at the code, it seems to do an autocrop, and then resize the image and the (or a) layer to the smallest square containing the cropped area. Commented Oct 6, 2016 at 13:24

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.