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
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 – Matthew Morrone Aug 11 '16 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 Aug 11 '16 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. – Matthew Morrone Aug 12 '16 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 Aug 13 '16 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 – Matthew Morrone Aug 21 '16 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 Sep 27 '16 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. – Matthew Morrone Sep 27 '16 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. – Michael Schumacher Oct 6 '16 at 13:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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