Batch Editing with Gimp Script-fu

A couple of days I posted a short script, that did a few very simple tasks – that was just a start, to help me get into Gimp Scripting, and help with a little job.

Today’s task is quite a bit meatier.

I’m doing tech for a play, and I want a copy of the script that I can mark up. I’ve scanned the whole thing, but it has all the usual problems with scans – pages aren’t aligned, background isn’t white, and you can see text on the other side of the page showing through.

All these can be fixed, and some even automated.

I’m not enough of an image processing wizard to fix the alignment automatically, but Gimp’s rotate and crop tools should do you proud! I found the Fixed->Size option in Rectangle Select very useful for getting all the output images the same size.

The script does the rest, read the comments (anything after a “;” on a line) to see how it works.

(script-fu-register
            "script-fu-scan-text-enhance"  ;func name
            "Scanned Text Enhance"         ;menu label
            "Scanned Text Enhancement"     ;description
            "Sandy Scott"                  ;author
            "Copyright 2013, Sandy Scott"  ;copyright notice
            "August 4, 2013"               ;date created
            "*"                            ;image type that the script works on
            SF-IMAGE       "Input image" 0
            SF-DRAWABLE    "Input drawable" 0 
            )
(script-fu-menu-register "script-fu-scan-text-enhance" "/Filters/Text")

(define (script-fu-scan-text-enhance image drawable)

    (let* ( )    
        
        ; Prep
        (gimp-context-push)
        (gimp-image-undo-group-start image)
        
        ; Actual work here
        
        ; Duplicate Layer
        (gimp-image-insert-layer image (car (gimp-layer-copy (car (gimp-image-get-active-layer image)) FALSE)) 0 0)
        
        ; Threshold
        (gimp-threshold (car  (gimp-image-get-active-drawable image)) 127 255)
        
        ; Select by Colour
        (gimp-context-set-antialias TRUE)
        (gimp-context-set-feather TRUE)
        (gimp-context-set-feather-radius 1.5 1.5)
        (gimp-context-set-sample-merged FALSE)
        (gimp-context-set-sample-threshold-int 1)
        (gimp-context-set-sample-transparent FALSE)
        (gimp-image-select-color image CHANNEL-OP-REPLACE (car  (gimp-image-get-active-drawable image)) '(0 0 0))
        
        ; Grow Selection
        (gimp-selection-grow image 1)
        (gimp-selection-invert image)
        
        ; Hide Duplicated Layer
        (gimp-item-set-visible (car  (gimp-image-get-active-drawable image)) FALSE)
        
        ; Activate Bottom Layer
        (gimp-image-set-active-layer image (vector-ref (cadr (gimp-image-get-layers image)) (- (vector-length (cadr (gimp-image-get-layers image))) 1)))
        
        
        ; Fill Selection with White
        (gimp-edit-fill (car  (gimp-image-get-active-drawable image)) WHITE-FILL)
        
        ; Clear Selection
        (gimp-selection-none image)
        
        ; Finishing Off
        (gimp-image-undo-group-end image)
        (gimp-context-pop)
        (gimp-displays-flush)
    )
)

Save with a .scm file extension put this in your scripts Directory (go to Edit->Preferences->Folders->Scripts if you don’t know where that is) then reload scripts (Filters->Script-Fu->Refresh Scripts). It should appear as Filters->Text->Scanned Text Enhance.

That’s all well and good if you’ve only got one image. What if you’ve got 80? Let’s automate this with a script.

The above script does the actual work of manipulating the image – the next one does the donkey work of loading the file, starting the manipulation script, then saving the file. In this case, it just saves over the old file, so make sure you’ve got a copy of the original in case it goes wrong. This should also be saved with a .scm extension in your scripts directory.

(define (scan-text-enhance filename)
    (let* (
            (image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
            (drawable (car (gimp-image-get-active-layer image))) )
        (script-fu-loot-prep2 image drawable)
        (gimp-file-save RUN-NONINTERACTIVE image drawable filename filename)
        (gimp-image-delete image)
    )
)

This has helped a bit – this script allows us run the text processing with only one piece of information – the filename, but how do you run it?
Type this into your command line:

"C:\Program Files\GIMP 2\bin\gimp-console-2.8.exe" -i -b "(scan-text-enhance \"filename.png\")" -b "(gimp-quit 0)"

You might need to change the path to your installation of Gimp, and also filename.png to the path to your image.

Finally, to automate this, I’m going to use a batch file. Make a batch file with this text:

for %%x in (*.png) do "C:\Program Files\GIMP 2\bin\gimp-console-2.8.exe" -i -b "(script-enhance \"%%x\")" -b "(gimp-quit 0)"

This will run our script on all the .png images in the current directory.

Thanks to:
Gimp Tutorials: GIMP Batch Mode
Gimp Docs: A Script-Fu Tutorial
SuperUser: Windows batch processing images with gimp and saving them to new files

Leave a Reply

Your email address will not be published. Required fields are marked *