Eleno
Eleno

Reputation: 3016

Resize image by percentage on both x and y on command line with Gimp

AFAIK, it should be possible. I know that convert of ImageMagick makes this task trivial, but I cannot use ImageMagick, therefore I am leaning towards Gimp (on Windows).

I have tried with this Guile script:

(define (resize-image filename new-filename scale)
  (let* ((image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
         (drawable (car (gimp-image-get-active-layer image)))
         (width (gimp-image-width image))
         (height (gimp-image-height image)))
    (gimp-image-scale-full image (* width scale) (* height scale) INTERPOLATION-CUBIC)
    (gimp-file-save RUN-NONINTERACTIVE image drawable new-filename new-filename)
    (gimp-image-delete image)))

that I run with:

gimp-2.8 -i -b "(resize-image \"image.jpg\" \"image-small.jpg\" 0.5)" -b "(gimp-quit 0)"

but I get this error:

(gimp-2.8:22244): LibGimpBase-WARNING **: gimp-2.8: gimp_wire_read(): error

(gimp-2.8:22244): LibGimpBase-WARNING **: gimp-2.8: gimp_wire_read(): error
batch command experienced an execution error:
Error: ( : 1) *: argument 1 must be: number

My solution has been inspired by this post:

http://warunapw.blogspot.it/2010/01/batch-resize-images-in-gimp.html

Upvotes: 5

Views: 4930

Answers (1)

xenoid
xenoid

Reputation: 8904

The shortest code to scale down an image:

image=pdb.gimp_file_load('/tmp/bigger.png','/tmp/bigger.png')
image.scale(int(image.width*.5),int(image.height*.5))
pdb.gimp_file_save(image, image.active_layer, '/tmp/smaller.png','/tmp/smaller.png')

So, you can still put everything in a one liner. In Linux, that gives (brace yourself):

gimp -idf --batch-interpreter python-fu-eval -b 'image=pdb.gimp_file_load("/tmp/bigger.png","/tmp/bigger.png");image.scale(int(image.width*.5),int(image.height*.5));pdb.gimp_file_save(image, image.active_layer, "/tmp/smaller.png","/tmp/smaller.png")' -b 'pdb.gimp_quit(1)'

IIRC, due to how to the Windows shell uses quotes, you have to use double quotes to delimit shell parameters so things are easier if you use single quotes around Python strings (untested):

gimp -idf --batch-interpreter python-fu-eval -b "image=pdb.gimp_file_load('/tmp/bigger.png','/tmp/bigger.png');image.scale(int(image.width*.5),int(image.height*.5));pdb.gimp_file_save(image, image.active_layer, '/tmp/smaller.png','/tmp/smaller.png')" -b "pdb.gimp_quit(1)"

However, there is significant overhead when starting Gimp (especially on WIndows), so if you need to process several files, you may be better off writing code that loops over files in a directory. This gets a bit bigger and may want to keep the code in a module. From my archives from a former life as a windows user:

Assume you have a batch.py file like this (you'll obviously have to improve the process() function, in particular pass parameters to it:

#!/usr/bin/python
# -*- coding: iso-8859-15 -*-
import os,glob,sys,time
from gimpfu import *

def process(infile):
    print "Processing file %s " % infile
    image=pdb.gimp_file_load('/tmp/bigger.png','/tmp/bigger.png');
    image.scale(int(image.width*.5),int(image.height*.5));
    pdb.gimp_file_save(image, image.active_layer, '/tmp/smaller.png','/tmp/smaller.png')
    pdb.gimp_image_delete(image)

def run(directory):
    start=time.time()
    print "Running on directory \"%s\"" % directory
    for infile in glob.glob(os.path.join(directory, '*.jpg')):
            process(infile)
    end=time.time()
    print "Finished, total processing time: %.2f seconds" % (end-start)

if __name__ == "__main__":
        print "Running as __main__ with args: %s" % sys.argv

You would call it (in Windows) as:

gimp -idf --batch-interpreter python-fu-eval -b "import sys;sys.path=['.']+sys.path;import batch;batch.run('./images')" -b "pdb.gimp_quit(1)"

Upvotes: 5

Related Questions