You are here

Divide Scanned Images

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
Rate this item!
AttachmentSize
DivideScannedImages.scm14.18 KB
deskew.zip21.61 KB

A script that will detect multiple images within a single image, crop them, optionally straighten them, and save them out with incrementing filenames+numbers. It was developed to aid in separating photos scanned on a flatbed scanner as one "image".

There is a big discussion thread over at gimptalk on this: http://www.gimptalk.com/forum/viewtopic.php?f=9&t=36438

The script also provides a batch mode to process a while directory of scanned images pages.

Note that the straightening will only work if you have the deskew plugin installed: http://www.cubewano.org/gimp-deskew-plugin/

***Since this site is down, i have attached a windows precompiled binary of the deskew plugin for convenience.

Code License: 
GIMP Version: 
Scripting Engine: 

Comments

If you google this Batch tool for separating scanned photos in one A4, there are a lot of literature but few solutions really effective. And this is the one that REALLY works. I have to say thanks, but also propose the script should have a README explaining inside out how to twick the options menu when using this script. I play around and discover the importance of 3 things:
1) Background sample tries to find the color of the background. So I have sorted out the source images depending on which corner is the white background
2) Abort Limit: I set it up to 85 and still results were good. No clear to me what is this for
3) Results: major issue is this script does not slide images that are scanned touching the scanner border, since this border is not same color as background. The advantage of a batch scanning is the ability to use the four borders of the scanner to align photos and avoid skew step. To solve this issue I used PHATCH IMAGE PROCESSOR to a) cut 5 pixels of the whole batch of A4 scanned images b) Add 25 pixels of the same color of my background c) save as PNG. Note: To measure the color of the background I used GIMP pick color option in "tools". I successfully run the script later.
Another frequent error when scanning is to scan a photo twice or simply scan several copies of the same photo. For detecting Duplicates you can use DIGIKAM. Tools-Find Duplicates.
I congratulate but also encourage the script owner to include at least point 3 as an option in the script code. Many thanks

This is a great script, and it works most of the time for me. I have a suggestion for just another cropping mode: "pre-selected cropping and saving".
The user has opened his "multiple-small-images" image. Then he selects several small images with the bounding box tool, holding Shift each time he adds an additional small image. After selection is finished, the user now runs the runs the "Pre-selected cropping and saving" script. Each bounding box is exported to an image, with automatic file name creation (e.g. image001.jpg, image002.jpg, image003.jpg ...)

Installation Notes for Gimp 2.8:

The scripts folder has moved slightly in Gimp 2.8 (on OS X Mountain Lion). You can see where your scripts folder is by going to Preferences->Folders->Scripts. Restart Gimp after you copy the script there.

The script: "Divide Scanned Images..." shows up at the top level of the Filters menu near the bottom. The Batch version is also in the Filters menu near the bottom under Batch Tools.

If the script is not showing up, and Gimp is not throwing any errors, you are probably either 1) using the wrong scripts directory, or 2) using one of the user-posted versions from the comments.

If you use one of the versions users have posted in the comments, the script will not show up in the Gimp menus because certain characters in the versions they posted got removed automatically by the website. You can fix that by editing the script and searching for the first occurrence of:
script-fu-register
Then change the line immediately after that from:
"/Filters/Divide Scanned Images..."
to:
"<Image>/Filters/Divide Scanned Images..."
and restarting gimp.

However, other parts of the user-posted scripts may also be corrupted similarly, as someone already pointed out.

Thx for the answer! I have installed it and it works. but my problem is that i dont know how the batch works. so when i open the program and go to filters > batch tools > batch divide scanned images, i get a window where you need to select things and fill in certain numbers but i dont know what all those things mean so i dont know what to fill out. for example the "selection treshold" and "size treshold" and "abort limit" and the things with the background. i want to know this because i have over a 100 images and every image that consist out of 4 other images that are proportionally divided. every image is 15x10. so easily said i have to divide 4 squares out of 1 square. I think this is a easy and quick way for me to divide all those images at the same time. could you help me out? hope so!

Hi all,
I have a question. I have been searching for ages for the answer how to divide 4 photographs that have been scanned at once. I think that this batch is the answer so i have downloaded it but i dont quite know how it works. So could you help me with the steps? I would like to know what do i have to select or insert in the "batch divide scanned images"- tool to seperate 4 images from one document.
Would like to hear from you, thx.

I've added in new script-fu-menu-register lines to make this work with current Gimp versions. Tested with Gimp 2.6.12 on Windows 7 Pro 64bit.
=================

; DivideScannedImages.scm
; by Rob Antonishen
; http://ffaat.pointclark.net

; Version 1.9 (20101007)

; Description
;
; Locates each separate element and creates a new image from each.
; will call the deskew plugin http://www.cubewano.org/gimp-deskew-plugin/
; if it is installed on each image
;
; Changes:
; v1.1 - Added a size threshold slider, and it will call the deskew plugin if installed
; v1.2 - takes a rectangular selection bounding the path rather than a selection from the path itself, added an abort threshold incase the parameters are wonky
; v1.3 - simplifies the selection via feather/sharpen first to speed up the image analysis.
; - fixed exporting the whole image as one.
; - added sliders to pick a background offset. This is useful if your scanner has a "shadow" around the edge of full scans,
; v1.4 - added the ability to save out dividede images to a directory with an incremental filename and number
; v1.5 - added corner selection to background pick
; v1.6 - changed global buffer use to named buffers
; v1.7 - added batch mode for whole directories, plus bug fix for no deskew plugin and saving files, also a fix to get both cases of file
; v1.8 - should now work on both windows and linux using the pathchar def.
; v1.9 - added sort code to the batch script

; License:
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; The GNU Public License is available at
; http://www.gnu.org/copyleft/gpl.html

(define (script_fu_DivideScannedImages img inLayer inThreshold inSize inLimit inCorner inX inY inSaveFiles inDir inSaveType inFileName inFileNumber)
(let*
(
(width (car (gimp-image-width img)))
(height (car (gimp-image-height img)))
(newpath 0)
(strokes 0)
(tempVector 0)
(tempImage 0)
(tempLayer 0)
(bounds 0)
(count 0)
(numextracted 0)
(saveString "")
(newFileName "")
(tempdisplay 0)
(buffname "dsibuff")
(pathchar (if (equal? (substring gimp-dir 0 1) "/") "/" "\\"))
)
; it begins here
(gimp-context-push)
(gimp-image-undo-disable img)

;logging
;(gimp-message-set-handler ERROR-CONSOLE)
;(gimp-message-set-handler CONSOLE)
;(gimp-message-set-handler MESSAGE-BOX)
;or start GIMP wwith "gimp --console-messages" to spawn a console box
;then use this:
;(gimp-message "foobar")

;testing for functions defined
;(if (defined? 'plug-in-shift) (gimp-message "It Exists") (gimp-message "Doesnt Exist"))

;set up saving
(if (= inSaveFiles TRUE)
(set! saveString
(cond
(( equal? inSaveType 0 ) ".jpg" )
(( equal? inSaveType 1 ) ".bmp" )
(( equal? inSaveType 2 ) ".png" )
)
))

; Expand the image a bit to fix problem with images near the right edge. Probably could get away just expanding
; width but go ahead and expand height in case same issue is there...
(set! width (+ width 30))
(set! height (+ height 30))
(gimp-image-resize img width height 0 0)
(gimp-layer-resize-to-image-size inLayer)

; convert in inverted copy of the background selection to a path using the selected corner
(cond
( (equal? inCorner 0)
(gimp-fuzzy-select inLayer inX inY inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer inX inY FALSE FALSE 0)))
)
( (equal? inCorner 1)
(gimp-fuzzy-select inLayer (- width inX) inY inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer (- width inX) inY FALSE FALSE 0)))
)
( (equal? inCorner 2)
(gimp-fuzzy-select inLayer inX (- height inY) inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer inX (- height inY) FALSE FALSE 0)))
)
( (equal? inCorner 3)
(gimp-fuzzy-select inLayer (- width inX) (- height inY) inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer (- width inX) (- height inY) FALSE FALSE 0)))
)
)
(gimp-selection-feather img (/ (min width height) 100))
(gimp-selection-sharpen img)
(gimp-selection-invert img)
(plug-in-sel2path RUN-NONINTERACTIVE img inLayer)

;break up the vectors
(set! newpath (vector-ref (cadr (gimp-image-get-vectors img)) 0))

(set! strokes (gimp-vectors-get-strokes newpath))
(while (and (< count (car strokes)) (< numextracted inLimit))

(set! tempVector (gimp-vectors-new img "Temp"))
(gimp-image-add-vectors img (car tempVector) -1)
(gimp-vectors-stroke-new-from-points (car tempVector)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 0)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 1)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 2)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 3)
)
(gimp-vectors-to-selection (car tempVector) CHANNEL-OP-REPLACE TRUE FALSE 0 0)

;check for minimum size
(set! bounds (gimp-selection-bounds img))
(if (and (> (- (list-ref bounds 3) (list-ref bounds 1)) inSize) (> (- (list-ref bounds 4) (list-ref bounds 2)) inSize) ;min size slider
(< (- (list-ref bounds 3) (list-ref bounds 1)) width) (< (- (list-ref bounds 4) (list-ref bounds 2)) height)) ;max size image
(begin
(gimp-rect-select img (list-ref bounds 1) (list-ref bounds 2)
(- (list-ref bounds 3) (list-ref bounds 1)) (- (list-ref bounds 4) (list-ref bounds 2))
CHANNEL-OP-REPLACE FALSE 0 )
(set! buffname (car (gimp-edit-named-copy inLayer buffname)))
(set! tempImage (car (gimp-edit-named-paste-as-new buffname)))
(set! tempLayer (car (gimp-image-get-active-layer tempImage)))
(gimp-image-undo-disable tempImage)
(set! tempdisplay (car (gimp-display-new tempImage)))

;run deskew if it is installed
(if (defined? 'gimp-deskew-plugin)
(begin
(gimp-progress-set-text "Deskewing...")
(gimp-layer-flatten tempLayer)
(gimp-deskew-plugin 0 tempImage tempLayer 0 0 0 0 0)
(gimp-image-resize-to-layers tempImage)
(gimp-layer-flatten tempLayer)
(gimp-fuzzy-select tempLayer 0 0 inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-selection-invert tempImage)
(set! bounds (gimp-selection-bounds tempImage))
(gimp-selection-none tempImage)
(gimp-image-crop tempImage (- (list-ref bounds 3) (list-ref bounds 1)) (- (list-ref bounds 4) (list-ref bounds 2))
(list-ref bounds 1) (list-ref bounds 2))
)
)
(gimp-image-undo-enable tempImage)

;save file
(if (= inSaveFiles TRUE)
(begin
(set! newFileName (string-append inDir pathchar inFileName
(substring "00000" (string-length (number->string (+ inFileNumber numextracted))))
(number->string (+ inFileNumber numextracted)) saveString))
(gimp-file-save RUN-NONINTERACTIVE tempImage tempLayer newFileName newFileName)
(gimp-display-delete tempdisplay)
)
)

(set! numextracted (+ numextracted 1))
)
)
(gimp-image-remove-vectors img (car tempVector))
(set! count (+ count 1))
)

;input drawable name should be set to 1919191919 if in batch
(if (and (> numextracted 0) (equal? (car (gimp-drawable-get-name inLayer)) "1919191919"))
(gimp-drawable-set-name inLayer (number->string (+ 1919191919 numextracted))))

;delete temp path
(gimp-image-remove-vectors img newpath)
(gimp-selection-none img)

;done
(gimp-image-undo-enable img)
(gimp-progress-end)
(gimp-displays-flush)
(gimp-context-pop)
)
)

(script-fu-register "script_fu_DivideScannedImages"
"Divide Scanned Images..."
"Attempts to isolate each part of the image from the background and creates a new image from it"
"Rob Antonishen"
"Rob Antonishen"
"Dec 2008"
"RGB* GRAY*"
SF-IMAGE "image" 0
SF-DRAWABLE "drawable" 0
SF-ADJUSTMENT "Selection Threshold" (list 10 0 255 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Size Threshold" (list 100 0 2000 10 100 1 SF-SLIDER)
SF-ADJUSTMENT "Abort Limit" (list 5 1 100 1 10 1 SF-SLIDER)
SF-OPTION "Background Sample Corner" (list "Top Left" "Top Right" "Bottom Left" "Bottom Right")
SF-ADJUSTMENT "Background Sample X Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Background Sample Y Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-TOGGLE "Save and Close Extracted Images" FALSE
SF-DIRNAME "Save Directory" ""
SF-OPTION "Save File Type" (list "jpg" "bmp" "png")
SF-STRING "Save File Base Name" "IMAGE"
SF-ADJUSTMENT "Save File Start Number" (list 0 0 9000 1 100 0 SF-SPINNER)
)

;line added by Jordan Nash in February 2012 (tested in Windows 7 Pro 64bit with Gimp 2.6.12)
(script-fu-menu-register "script_fu_DivideScannedImages"
"/_Filters/_Script-Fu")

(define (script_fu_BatchDivideScannedImages inSourceDir inLoadType inThreshold inSize inLimit inCorner inX inY inDestDir inSaveType inFileName inFileNumber)
(let*
(
(varLoadStr "")
(varFileList 0)
(varCounter inFileNumber)
(pathchar (if (equal? (substring gimp-dir 0 1) "/") "/" "\\"))
)

(define split
(lambda (ls)
(letrec ((split-h (lambda (ls ls1 ls2)
(cond
((or (null? ls) (null? (cdr ls)))
(cons (reverse ls2) ls1))
(else (split-h (cddr ls)
(cdr ls1) (cons (car ls1) ls2)))))))
(split-h ls ls '()))))

(define merge
(lambda (pred ls1 ls2)
(cond
((null? ls1) ls2)
((null? ls2) ls1)
((pred (car ls1) (car ls2))
(cons (car ls1) (merge pred (cdr ls1) ls2)))
(else (cons (car ls2) (merge pred ls1 (cdr ls2)))))))

;pred is the comparison, i.e. <= for an ascending numeric list, or
;string<=? for a case sensitive alphabetical sort,
;string-ci<=? for a case insensitive alphabetical sort,
(define merge-sort
(lambda (pred ls)
(cond
((null? ls) ls)
((null? (cdr ls)) ls)
(else (let ((splits (split ls)))
(merge pred
(merge-sort pred (car splits))
(merge-sort pred (cdr splits))))))))

;begin here
(set! varLoadStr
(cond
(( equal? inLoadType 0 ) ".[jJ][pP][gG]" )
(( equal? inLoadType 1 ) ".[bB][mM][pP]" )
(( equal? inLoadType 2 ) ".[pP][nN][gG]" )
))

(set! varFileList (merge-sort string<=? (cadr (file-glob (string-append inSourceDir pathchar "*" varLoadStr) 1))))
(while (not (null? varFileList))
(let* ((filename (car varFileList))
(image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
(drawable (car (gimp-image-get-active-layer image))))

;flag for batch mode
(gimp-drawable-set-name drawable "1919191919")
(gimp-progress-set-text (string-append "Working on ->" filename))

(script_fu_DivideScannedImages image drawable inThreshold inSize inLimit inCorner inX inY TRUE inDestDir inSaveType inFileName varCounter)

;increment by number extracted.
(set! varCounter (+ varCounter (- (string->number (car (gimp-drawable-get-name drawable))) 1919191919)))
(gimp-image-delete image)
)
(set! varFileList (cdr varFileList))
)
)
)

(script-fu-register "script_fu_BatchDivideScannedImages"
"Batch Divide Scanned Images..."
"Batch devide a folder of full page scans images."
"Rob Antonishen"
"Rob Antonishen"
"May 2009"
""
SF-DIRNAME "Load from" ""
SF-OPTION "Load File Type" (list "jpg" "bmp" "png")
SF-ADJUSTMENT "Selection Threshold" (list 10 0 255 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Size Threshold" (list 100 0 2000 10 100 1 SF-SLIDER)
SF-ADJUSTMENT "Abort Limit" (list 5 1 100 1 10 1 SF-SLIDER)
SF-OPTION "Background Sample Corner" (list "Top Left" "Top Right" "Bottom Left" "Bottom Right")
SF-ADJUSTMENT "Background Sample X Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Background Sample Y Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-DIRNAME "Save Directory" ""
SF-OPTION "Save File Type" (list "jpg" "bmp" "png")
SF-STRING "Save File Base Name" "IMAGE"
SF-ADJUSTMENT "Save File Start Number" (list 0 0 9000 1 100 0 SF-SPINNER)
)

;line added by Jordan Nash in February 2012 (tested in Windows 7 Pro 64bit with Gimp 2.6.12)
(script-fu-menu-register "script_fu_BatchDivideScannedImages"
"/_Filters/_Script-Fu")

==========================

Thanks very much for the update.

Unfortunately, the comment mechanism is not good for recording source code: things get lost.
Anything with angle-brackets got lost.
Indentation got lost.
Whitespace got collapsed.

With some work, I've tried to reconstruct your changes to the original. I've placed it in http://pastebin.ca/2173647

You seem to have added 3 chunks.


; Expand the image a bit to fix problem with images near the right edge. Probably could get away just expanding
; width but go ahead and expand height in case same issue is there...
(set! width (+ width 30))
(set! height (+ height 30))
(gimp-image-resize img width height 0 0)
(gimp-layer-resize-to-image-size inLayer)


;line added by Jordan Nash in February 2012 (tested in Windows 7 Pro 64bit with Gimp 2.6.12)
(script-fu-menu-register "script_fu_DivideScannedImages"
"/_Filters/_Script-Fu")


;line added by Jordan Nash in February 2012 (tested in Windows 7 Pro 64bit with Gimp 2.6.12)
(script-fu-menu-register "script_fu_BatchDivideScannedImages"
"/_Filters/_Script-Fu")

In the last two chunks, I think &LT;Toolbox&GT; is missing from the two paths. But when I add this, I get the following messages from gimp:

GIMP-Error: Plug-in "script-fu"
(/usr/lib64/gimp/2.0/plug-ins/script-fu)
attempted to register the menu item "&LT;Toolbox&GT;/_Filters/_Script-Fu" for procedure "script-fu-DivideScannedImages".
The menu label given in gimp_install_procedure() already contained a path. To make this work, pass just the menu's label to gimp_install_procedure().

GIMP-Error: Plug-in "script-fu"
(/usr/lib64/gimp/2.0/plug-ins/script-fu)
attempted to register the menu item "&LT;Toolbox&GT;/_Filters/_Script-Fu" for procedure "script-fu-BatchDivideScannedImages".
The menu label given in gimp_install_procedure() already contained a path. To make this work, pass just the menu's label to gimp_install_procedure().

I'm new at this -- this is the first time I've used the gimp, let alone tried to play with plugins and scripts. Help would be appreciated!

While the script as uploaded does register the script and register the menu entry in one call this should work fine in 2.6 It does on my system.

-Rob A>

I modified script to fix issue with images on the edge.

(modified script a bit to deal with left and top as well...)

====
; DivideScannedImages.scm
; by Rob Antonishen
; http://ffaat.pointclark.net

; Version 2.0 (20123108)

; Description
;
; Locates each separate element and creates a new image from each.
; will call the deskew plugin http://www.cubewano.org/gimp-deskew-plugin/
; if it is installed on each image
;
; Changes:
; v1.1 - Added a size threshold slider, and it will call the deskew plugin if installed
; v1.2 - takes a rectangular selection bounding the path rather than a selection from the path itself, added an abort threshold incase the parameters are wonky
; v1.3 - simplifies the selection via feather/sharpen first to speed up the image analysis.
; - fixed exporting the whole image as one.
; - added sliders to pick a background offset. This is useful if your scanner has a "shadow" around the edge of full scans,
; v1.4 - added the ability to save out dividede images to a directory with an incremental filename and number
; v1.5 - added corner selection to background pick
; v1.6 - changed global buffer use to named buffers
; v1.7 - added batch mode for whole directories, plus bug fix for no deskew plugin and saving files, also a fix to get both cases of file
; v1.8 - should now work on both windows and linux using the pathchar def.
; v1.9 - added sort code to the batch script
; v2.0 - expand image on edges so that selection works properly

; License:
;
; This program is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.
;
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; The GNU Public License is available at
; http://www.gnu.org/copyleft/gpl.html

(define (script_fu_DivideScannedImages img inLayer inThreshold inSize inLimit inCorner inX inY inSaveFiles inDir inSaveType inFileName inFileNumber)
(let*
(
(width (car (gimp-image-width img)))
(height (car (gimp-image-height img)))
(newpath 0)
(strokes 0)
(tempVector 0)
(tempImage 0)
(tempLayer 0)
(bounds 0)
(count 0)
(numextracted 0)
(saveString "")
(newFileName "")
(tempdisplay 0)
(buffname "dsibuff")
(pathchar (if (equal? (substring gimp-dir 0 1) "/") "/" "\\"))
)
; it begins here
(gimp-context-push)
(gimp-image-undo-disable img)

;logging
;(gimp-message-set-handler ERROR-CONSOLE)
;(gimp-message-set-handler CONSOLE)
;(gimp-message-set-handler MESSAGE-BOX)
;or start GIMP wwith "gimp --console-messages" to spawn a console box
;then use this:
;(gimp-message "foobar")

;testing for functions defined
;(if (defined? 'plug-in-shift) (gimp-message "It Exists") (gimp-message "Doesnt Exist"))

;set up saving
(if (= inSaveFiles TRUE)
(set! saveString
(cond
(( equal? inSaveType 0 ) ".jpg" )
(( equal? inSaveType 1 ) ".bmp" )
(( equal? inSaveType 2 ) ".png" )
)
))

; Expand the image a bit to fix problem with images near the right edge. Probably could get away just expanding
; width but go ahead and expand height in case same issue is there...
(set! width (+ width 30))
(set! height (+ height 30))
(gimp-image-resize img width height 15 15)
(gimp-layer-resize-to-image-size inLayer)

; convert in inverted copy of the background selection to a path using the selected corner
(cond
( (equal? inCorner 0)
(gimp-fuzzy-select inLayer inX inY inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer inX inY FALSE FALSE 0)))
)
( (equal? inCorner 1)
(gimp-fuzzy-select inLayer (- width inX) inY inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer (- width inX) inY FALSE FALSE 0)))
)
( (equal? inCorner 2)
(gimp-fuzzy-select inLayer inX (- height inY) inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer inX (- height inY) FALSE FALSE 0)))
)
( (equal? inCorner 3)
(gimp-fuzzy-select inLayer (- width inX) (- height inY) inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-context-set-background (car (gimp-image-pick-color img inLayer (- width inX) (- height inY) FALSE FALSE 0)))
)
)
(gimp-selection-feather img (/ (min width height) 100))
(gimp-selection-sharpen img)
(gimp-selection-invert img)
(plug-in-sel2path RUN-NONINTERACTIVE img inLayer)

;break up the vectors
(set! newpath (vector-ref (cadr (gimp-image-get-vectors img)) 0))

(set! strokes (gimp-vectors-get-strokes newpath))
(while (and (< count (car strokes)) (< numextracted inLimit))

(set! tempVector (gimp-vectors-new img "Temp"))
(gimp-image-add-vectors img (car tempVector) -1)
(gimp-vectors-stroke-new-from-points (car tempVector)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 0)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 1)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 2)
(list-ref (gimp-vectors-stroke-get-points newpath (vector-ref (cadr strokes) count)) 3)
)
(gimp-vectors-to-selection (car tempVector) CHANNEL-OP-REPLACE TRUE FALSE 0 0)

;check for minimum size
(set! bounds (gimp-selection-bounds img))
(if (and (> (- (list-ref bounds 3) (list-ref bounds 1)) inSize) (> (- (list-ref bounds 4) (list-ref bounds 2)) inSize) ;min size slider
(< (- (list-ref bounds 3) (list-ref bounds 1)) width) (< (- (list-ref bounds 4) (list-ref bounds 2)) height)) ;max size image
(begin
(gimp-rect-select img (list-ref bounds 1) (list-ref bounds 2)
(- (list-ref bounds 3) (list-ref bounds 1)) (- (list-ref bounds 4) (list-ref bounds 2))
CHANNEL-OP-REPLACE FALSE 0 )
(set! buffname (car (gimp-edit-named-copy inLayer buffname)))
(set! tempImage (car (gimp-edit-named-paste-as-new buffname)))
(set! tempLayer (car (gimp-image-get-active-layer tempImage)))
(gimp-image-undo-disable tempImage)
(set! tempdisplay (car (gimp-display-new tempImage)))

;run deskew if it is installed
(if (defined? 'gimp-deskew-plugin)
(begin
(gimp-progress-set-text "Deskewing...")
(gimp-layer-flatten tempLayer)
(gimp-deskew-plugin 0 tempImage tempLayer 0 0 0 0 0)
(gimp-image-resize-to-layers tempImage)
(gimp-layer-flatten tempLayer)
(gimp-fuzzy-select tempLayer 0 0 inThreshold CHANNEL-OP-REPLACE TRUE FALSE 0 TRUE)
(gimp-selection-invert tempImage)
(set! bounds (gimp-selection-bounds tempImage))
(gimp-selection-none tempImage)
(gimp-image-crop tempImage (- (list-ref bounds 3) (list-ref bounds 1)) (- (list-ref bounds 4) (list-ref bounds 2))
(list-ref bounds 1) (list-ref bounds 2))
)
)
(gimp-image-undo-enable tempImage)

;save file
(if (= inSaveFiles TRUE)
(begin
(set! newFileName (string-append inDir pathchar inFileName
(substring "00000" (string-length (number->string (+ inFileNumber numextracted))))
(number->string (+ inFileNumber numextracted)) saveString))
(gimp-file-save RUN-NONINTERACTIVE tempImage tempLayer newFileName newFileName)
(gimp-display-delete tempdisplay)
)
)

(set! numextracted (+ numextracted 1))
)
)
(gimp-image-remove-vectors img (car tempVector))
(set! count (+ count 1))
)

;input drawable name should be set to 1919191919 if in batch
(if (and (> numextracted 0) (equal? (car (gimp-drawable-get-name inLayer)) "1919191919"))
(gimp-drawable-set-name inLayer (number->string (+ 1919191919 numextracted))))

;delete temp path
(gimp-image-remove-vectors img newpath)
(gimp-selection-none img)

;done
(gimp-image-undo-enable img)
(gimp-progress-end)
(gimp-displays-flush)
(gimp-context-pop)
)
)

(script-fu-register "script_fu_DivideScannedImages"
"/Filters/Divide Scanned Images..."
"Attempts to isolate each part of the image from the background and creates a new image from it"
"Rob Antonishen"
"Rob Antonishen"
"Dec 2008"
"RGB* GRAY*"
SF-IMAGE "image" 0
SF-DRAWABLE "drawable" 0
SF-ADJUSTMENT "Selection Threshold" (list 10 0 255 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Size Threshold" (list 100 0 2000 10 100 1 SF-SLIDER)
SF-ADJUSTMENT "Abort Limit" (list 5 1 100 1 10 1 SF-SLIDER)
SF-OPTION "Background Sample Corner" (list "Top Left" "Top Right" "Bottom Left" "Bottom Right")
SF-ADJUSTMENT "Background Sample X Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Background Sample Y Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-TOGGLE "Save and Close Extracted Images" FALSE
SF-DIRNAME "Save Directory" ""
SF-OPTION "Save File Type" (list "jpg" "bmp" "png")
SF-STRING "Save File Base Name" "IMAGE"
SF-ADJUSTMENT "Save File Start Number" (list 0 0 9000 1 100 0 SF-SPINNER)
)

(define (script_fu_BatchDivideScannedImages inSourceDir inLoadType inThreshold inSize inLimit inCorner inX inY inDestDir inSaveType inFileName inFileNumber)
(let*
(
(varLoadStr "")
(varFileList 0)
(varCounter inFileNumber)
(pathchar (if (equal? (substring gimp-dir 0 1) "/") "/" "\\"))
)

(define split
(lambda (ls)
(letrec ((split-h (lambda (ls ls1 ls2)
(cond
((or (null? ls) (null? (cdr ls)))
(cons (reverse ls2) ls1))
(else (split-h (cddr ls)
(cdr ls1) (cons (car ls1) ls2)))))))
(split-h ls ls '()))))

(define merge
(lambda (pred ls1 ls2)
(cond
((null? ls1) ls2)
((null? ls2) ls1)
((pred (car ls1) (car ls2))
(cons (car ls1) (merge pred (cdr ls1) ls2)))
(else (cons (car ls2) (merge pred ls1 (cdr ls2)))))))

;pred is the comparison, i.e. <= for an ascending numeric list, or
;string<=? for a case sensitive alphabetical sort,
;string-ci<=? for a case insensitive alphabetical sort,
(define merge-sort
(lambda (pred ls)
(cond
((null? ls) ls)
((null? (cdr ls)) ls)
(else (let ((splits (split ls)))
(merge pred
(merge-sort pred (car splits))
(merge-sort pred (cdr splits))))))))

;begin here
(set! varLoadStr
(cond
(( equal? inLoadType 0 ) ".[jJ][pP][gG]" )
(( equal? inLoadType 1 ) ".[bB][mM][pP]" )
(( equal? inLoadType 2 ) ".[pP][nN][gG]" )
))

(set! varFileList (merge-sort string<=? (cadr (file-glob (string-append inSourceDir pathchar "*" varLoadStr) 1))))
(while (not (null? varFileList))
(let* ((filename (car varFileList))
(image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))
(drawable (car (gimp-image-get-active-layer image))))

;flag for batch mode
(gimp-drawable-set-name drawable "1919191919")
(gimp-progress-set-text (string-append "Working on ->" filename))

(script_fu_DivideScannedImages image drawable inThreshold inSize inLimit inCorner inX inY TRUE inDestDir inSaveType inFileName varCounter)

;increment by number extracted.
(set! varCounter (+ varCounter (- (string->number (car (gimp-drawable-get-name drawable))) 1919191919)))
(gimp-image-delete image)
)
(set! varFileList (cdr varFileList))
)
)
)

(script-fu-register "script_fu_BatchDivideScannedImages"
"/Xtns/Batch Tools/Batch Divide Scanned Images..."
"Batch devide a folder of full page scans images."
"Rob Antonishen"
"Rob Antonishen"
"August 2012"
""
SF-DIRNAME "Load from" ""
SF-OPTION "Load File Type" (list "jpg" "bmp" "png")
SF-ADJUSTMENT "Selection Threshold" (list 10 0 255 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Size Threshold" (list 100 0 2000 10 100 1 SF-SLIDER)
SF-ADJUSTMENT "Abort Limit" (list 5 1 100 1 10 1 SF-SLIDER)
SF-OPTION "Background Sample Corner" (list "Top Left" "Top Right" "Bottom Left" "Bottom Right")
SF-ADJUSTMENT "Background Sample X Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-ADJUSTMENT "Background Sample Y Offset" (list 5 1 100 1 10 1 SF-SLIDER)
SF-DIRNAME "Save Directory" ""
SF-OPTION "Save File Type" (list "jpg" "bmp" "png")
SF-STRING "Save File Base Name" "IMAGE"
SF-ADJUSTMENT "Save File Start Number" (list 0 0 9000 1 100 0 SF-SPINNER)
)
====

THANKS!!! absolutely fantastic script! Worked perfectly, first time!

Pages

Subscribe to Comments for "Divide Scanned Images"