Re: Original ~600pg/hr, very portable scanner now achieving ~900pg-1100pg/hr
Posted: 08 Apr 2017, 12:48
Thanks and thanks for the tips. I'll try them out soon. In the mean time, here's an update to the script (V1.2).
a) It now asks you for both left and right directories (you can provide either or both) and processes them (one after the other).
b) It also creates the output (excluding the first and last calibration images) in sub-directories under each saving the hassle of backing things up and/or over-writing your original files by mistake.
a) It now asks you for both left and right directories (you can provide either or both) and processes them (one after the other).
b) It also creates the output (excluding the first and last calibration images) in sub-directories under each saving the hassle of backing things up and/or over-writing your original files by mistake.
Code: Select all
#singleinstance, force
; Normalize Scanned Pages Scale V1.2
;
; Autohotkey script using graphics magic library
;
; Rescale pages from a book with varying camera/platen distance (i.e. difference in distance from camera to first page and last page scanned is thickness of book)
; to normalize page scale so content on each page is same as first page (i.e. last page is scaled the most amount).
;
; File modified date and time of each image must increase from first (largest) to last (smallest) page scanned.
;
; ALL pages must be scanned (including blank) with equal number of pages in separate directories for left and right hand pages;
; Output is placed in a subdirectory of each (calibration pages are not processed or copied)
; Full path to graphicsmagick gm.exe
; Example: C:\Program Files\GraphicsMagick-1.3.25-Q8\gm.exe
gm := "C:\Program Files (x86)\GraphicsMagick-1.3.25-Q16\gm.exe"
if !FileExist(gm) {
MsgBox ,,ERROR,graphicsmagick's gm.exe file not found here:`n`n%gm%
exitapp
}
GetImageDirectories:
; Get path to folder with right and/or right hand page jpg images to process
rightOutput := "\right-adjusted"
leftOutput := "\left-adjusted"
rightImagesFolder := ""
leftImagesFolder := ""
FileSelectFolder, rightImagesFolder,,2,Choose folder with ALL right hand pages (or enter cancel to skip processing right hand pages)
FileSelectFolder, leftImagesFolder,,2,Choose folder with ALL right hand pages (or enter cancel to skip processing left hand pages)
If (rightImagesFolder = "" and leftImagesFolder = "") {
ExitApp
}
If (rightImagesFolder = leftImagesFolder) {
MsgBox ,,ERROR,You have chosen the same directory for both left and right hand pages. This is not allowed. Please choose the directories again.
goto GetImageDirectories
}
If (rightImagesFolder <> "") {
if !FileExist(rightImagesFolder) {
MsgBox ,,ERROR,Folder given for right hand images does not exist. Please choose both image directories again
goto GetImageDirectories
}
; Femove trailing slashes
rightImagesFolder := RegExReplace(rightImagesFolder, "\\$")
if FileExist(rightImagesFolder . rightOutput) {
FileRemoveDir, %rightImagesFolder%%rightOutput%
}
FileCreateDir, %rightImagesFolder%%rightOutput%
}
If (leftImagesFolder <> "") {
if !FileExist(leftImagesFolder) {
MsgBox ,,ERROR,Folder given for left hand images does not exist. Please choose both image directories again
goto GetImageDirectories
}
; Femove trailing slashes
leftImagesFolder := RegExReplace(leftImagesFolder, "\\$")
if FileExist(leftImagesFolder . leftOutput) {
FileRemoveDir, %leftImagesFolder%%leftOutput%
}
FileCreateDir, %leftImagesFolder%%leftOutput%
}
; Get number of pixels of calibration image (6" ruler) placed on first page and last page of book
GetCalibrationSizes:
firstImageSize := 0
While firstImageSize = 0 Or firstImageSize = "" {
InputBox, firstImageSize, First Calibration Page, Enter number of pixels taken by a 6`" ruler placed on the first page of the book (first callibration page),,450,130
if (ErrorLevel = 1) {
ExitApp
}
If (firstImageSize = 0 Or firstImageSize = "") {
MsgBox ,,ERROR,Zero or blank is not allowed
}
}
lastImageSize := 0
While lastImageSize = 0 Or lastImageSize = "" {
InputBox, lastImageSize, Last Calibration Page, Enter number of pixels taken by a 6`" ruler placed on the last page of the book (second callibration page),,450,130
if (ErrorLevel = 1) {
ExitApp
}
If (lastImageSize = 0 Or lastImageSize = "") {
MsgBox ,,ERROR,Zero or blank is not allowed
}
If (firstImageSize < lastImageSize) {
MsgBox ,,ERROR,Last/smallest image is greater than first/largest image. Please enter the values again.
goto GetCalibrationSizes
}
}
; Calculate scale difference (percentage) between first and last pages
totalScaleFactor := ( firstImageSize / lastImageSize ) * 100
; 8228=4+32+8192
MsgBox, 8228, WARNING, Processing images as follows`n`nRighthand images: %rightImagesFolder%`n`nLefthand images: %leftImagesFolder%`n`nPixel count (first image): %firstImageSize%`nPixel count (last image): %lastImageSize%`nFirst to last image scale factor: %totalScaleFactor%`n`nOk to proceed?
IfMsgBox, No
ExitApp
If (rightImagesFolder <> "") {
ProcessDirectory(rightImagesFolder, rightImagesFolder . rightOutput, "RIGHT")
}
If (leftImagesFolder <> "") {
ProcessDirectory(leftImagesFolder, leftImagesFolder . leftOutput, "LEFT")
}
exitapp
ProcessDirectory(currentInputImagesFolder, currentOutputImagesFolder, currentPageHand)
{
global totalScaleFactor
global gm
; noOfFiles number of pages in directory to scale can be distributed across all pages
; Create file list sorted by modified date/time so script can be used after renaming and is not depenedent on original image file name.
; Using time stamp also ensures processing is not random if directory listing is not alphabetic
fileList := ""
noOfFiles := 0
Loop, files, %currentInputImagesFolder%\*.jpg
{
; ignore first calibration image
if (noOfFiles <> 0) {
fileList = %FileList%%A_LoopFileTimeModified%`t%A_LoopFileName%`n
}
noOfFiles++
}
; remove last calibration page from file list (search for second `n)
fileList := Substr(fileList,1,Instr(fileList,"`n",false,-1,1))
; reduce count by 2 becuse 2 calibration images removed
noOfFiles := noOfFiles - 2
; Sort file list (date is appeneded to front of each entry of FileList - so list will be sorted by time first and then by file name)
; This lets many files with the same time (i.e. seconds didn't change) still sort in the right order and not dependent on
; Dir listings that may be in random order. Timestamp is not really needed and can be removed.
Sort, FileList
; Initalize the progress bar style
Progress, B2 M FM10 FS10 WM10 WS10 W700, Starting, PROCESSING %currentPageHand% HAND PAGES -- PRESS ESCAPE TO ABORT
Loop, Parse, fileList, `n
{
; Omit the last linefeed (blank item) at the end of the list.
if (A_LoopField = "")
break
; Split into two parts at the tab char.
StringSplit, FileItem, A_LoopField, %A_Tab%
; ignore first image coz not to be scaled
if (a_index = 1) {
FileCopy, %currentInputImagesFolder%\%FileItem2%, %currentOutputImagesFolder%\%FileItem2%
continue
}
thisImageScaleFactor := (totalScaleFactor - 100) * (a_index / noOfFiles) + 100
amountDone := floor(a_index/noOfFiles*100)
; Update the progress bar value
Progress, %amountDone%
; Display the progress bar at the new value with new text
Progress, ,Processing: %a_index%/%noOfFiles% -- Scale: %thisImageScaleFactor% -- %FileItem2%
RunWait "%gm%" convert "%currentInputImagesFolder%\%FileItem2%" -resize %thisImageScaleFactor%`% -quality 100 "%currentOutputImagesFolder%\%FileItem2%",,hide
; Just make sure we actually exit when done, just to make sure last file is not processed twice in case don't exit with the blank above (as that seems to fail sometimes)
if (a_index = noOfFiles)
break
}
Progress, Off
return
}
; Allow escape to cancel
Escape::ExitApp