This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
software:pdfprocessing:flattenandcompactpdf_a4size [2011/08/07 17:13] – [History] admin | software:pdfprocessing:flattenandcompactpdf_a4size [2011/08/22 22:31] (current) – removed admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== FlattenANDCompactPDF_a4size ====== | ||
- | ^ [[software: | ||
- | Please see for the source code below. | ||
- | |||
- | ===== Installation ===== | ||
- | The program has been written for and tested on a Microsoft Windows XP system with the script language [[http:// | ||
- | * Ghostscript: | ||
- | * Microsoft Visual C++ 2008 SP1: [[http:// | ||
- | * ImageMagick: | ||
- | |||
- | Once all files have been downloaded and installed, finally download: | ||
- | * The application FlattenANDCompactPDF_A4Size: | ||
- | * crc32 code: 0xa42de0ae | ||
- | ===== Usage ===== | ||
- | Either use drag and drop with your pdf or tif file(s) onto the exe, or add the file(s) as argument. | ||
- | ==== (Program filename) Options ==== | ||
- | * To specify the resolution, add either **-rNNN** or **-rNNNN** to your program name. For example if your exe file is called FlattenANDCompactPDF_A4Size.exe, | ||
- | * To add automatically empty pages at the end of the document when the amount of pages is not a multiple of 4, add **-q** to your program name. For example if your exe file is called FlattenANDCompactPDF_A4Size -r600.exe, rename it to FlattenANDCompactPDF_A4Size -r600 -q.exe | ||
- | |||
- | ===== History ===== | ||
- | * Changes in v0.8c, 7th of August 2011 | ||
- | * Added option to specify the output resolution((not fully tested)). | ||
- | * Added option to automatically add empty pages at the end of the document when the amount of pages is not a multiple of 4. If enabled, it will only add pages when the total amount of pages is at least 3. | ||
- | * Changes in v0.8b, 29th of July 2011 | ||
- | * Cleaning up code of the main process due to similarity between processing of tiff and pdf. | ||
- | * Fixed a minor bug with page sizes which were almost a4 and did not caused the algorithm to correct for rasterization rounding errors. | ||
- | * changed comments in the code. | ||
- | * Changes in v0.8, 28th of July 2011 | ||
- | * New feature: apart from pdf files, it now also accepts per drag and drop one or more .tif files, which are rescaled and converted so that the resulting file will be a pdf file with exactly a4 page dimensions. | ||
- | * Changes in v0.7, Februari 2010 | ||
- | * Optimize pdf conversion algorithm to increase speed. | ||
- | ===== Source code ===== | ||
- | Please note: the code is as is. No warranty is given, nor any support. | ||
- | < | ||
- | ; Alternatively tif files which are supplied per drag and drop are converted to pdf as well. | ||
- | ; Copyright (C) Februari 2010, August 2011 by Marc Nijdam | ||
- | ; | ||
- | ; 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 3 of the License, or | ||
- | ; 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. | ||
- | ; GNU General Public License for more details. | ||
- | ; | ||
- | ; You should have received a copy of the GNU General Public License | ||
- | ; along with this program. | ||
- | ; | ||
- | ; Contact details: http:// | ||
- | ; | ||
- | |||
- | # | ||
- | |||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #include < | ||
- | #Include < | ||
- | #Include < | ||
- | |||
- | Global Const $ThisProgramVersion = " | ||
- | Global Const $ThisProgramDate = " | ||
- | Global Const $ThisProgramName = " | ||
- | |||
- | ; Dependencies constants | ||
- | Global Const $Ghostscript_name = " | ||
- | Global Const $Ghostscript_RegPath = " | ||
- | Global Const $imagemagick_name = " | ||
- | Global Const $imagemagick_RegPath = " | ||
- | |||
- | ; Requires Imagemagick installation from http:// | ||
- | ; Path environment variable should be pointing to imagemagick, | ||
- | ; If not there, this script adds the following temporarily: | ||
- | ; | ||
- | ; This program requires Ghostscript, | ||
- | ; Path environment variable should be pointing to: %PROGRAMFILES%\gs\gs8.xx\bin; | ||
- | ; | ||
- | ; The following solves a R6034 (AutoIt3 related) error: | ||
- | ; http:// | ||
- | ; | ||
- | ; Nb.: | ||
- | ; Write an environment variable: EnvSet ( " | ||
- | ; ControlClick($parentWindowName," | ||
- | ; $CmdLine[0] = number of parameters | ||
- | ; $CmdLine[1] = first parameter | ||
- | ; Current temporary filename: pdf2tif00000_etcetera | ||
- | ; Optional parameters which can be added at the last part of the filename: | ||
- | ; -q -> This will make sure the pdf file has a multiple of 4 pages (Only if the document contains at | ||
- | ; least 3 pages). This option is a practical way to correct page layout with odd and even pages. | ||
- | ; It adds as many as necessary white pages at the end. For example, if your document consists | ||
- | ; of 7 pages, it will add one empty page at the end. The only necesary thing to do then is | ||
- | ; verify if the white page is at the correct location. A way to check this if page numbers | ||
- | ; appear on the inside instead of the outside of pages. | ||
- | ; -r300 -> Set resolution of your images in the pdf document. If not specified, it will default to 300dpi | ||
- | ; Error constants | ||
- | Global Const $_ERROR_MissingImageMagickObject = -1 | ||
- | Global Const $_ERROR_PdfInputFileIsNotValid = -2 | ||
- | Global Const $_ERROR_ShowHelp = -3 | ||
- | Global Const $_ERROR_PdfImageSizeTooLarge = -4 | ||
- | Global Const $_ERROR_CannotFindGhostscript = -5 | ||
- | Global Const $_ERROR_imagemagickNotInstalled = -6 | ||
- | Global Const $_ERROR_MSVisualCPlusPlus2008RedistNotInstalled = -7 | ||
- | Global Const $_ERROR_PDF_FileInconsistent = -8 | ||
- | |||
- | ; Gui constants | ||
- | Global Const $Gui_Title = $ThisProgramName | ||
- | Global $nEdit | ||
- | |||
- | ; program options | ||
- | ; $cmdOptions[$_QuadPages] -> False means no quadruple pages | ||
- | ; $cmdOptions[$_Resolution] -> resolution. All Files and all pages within a batch should have the same resolution. | ||
- | ; Initialize with adding empty pages disabled and a resolution of 300dpi | ||
- | Global Const $_OptionChr = ' | ||
- | Global Const $_QuadPages = 0 | ||
- | Global Const $_Resolution = 1 | ||
- | Dim $cmdOptions[2] = [ False, _ | ||
- | 300] | ||
- | parseCmdOptions(@ScriptName, | ||
- | |||
- | ; tif and pdf constants | ||
- | Global Const $rastering = 72 ; PDF rastering value | ||
- | Global Const $img_width = ($cmdOptions[$_Resolution]/ | ||
- | Global Const $img_height = ($cmdOptions[$_Resolution]/ | ||
- | Global Const $pdfdims[2] = [String(Int(($rastering*$img_width/ | ||
- | Global Const $bitmaperror = int($cmdOptions[$_Resolution]/ | ||
- | Global Const $tif = " | ||
- | Global Const $ps = " | ||
- | Global Const $pdf = " | ||
- | |||
- | ; program specific constants | ||
- | Global Const $Delay=400 ; Short waiting time necessary to retreive console output. | ||
- | Global Const $tempname = @TempDir & " | ||
- | Global Const $QQ = '"' | ||
- | Dim $szDrive, $szDir, $szFName, $szExt | ||
- | Dim $i , $j, $k | ||
- | Dim $Pdf_ListOfFiles2Proces = $tempname & " | ||
- | Dim $Pdf_tmp_FileName = $tempname & " | ||
- | ; ###################################################################################################### | ||
- | ; # main | ||
- | ; ###################################################################################################### | ||
- | |||
- | CheckAndSetEnv() ; Check dependencies and set environment variables | ||
- | GarbageControl($ThisProgramName) ; Cleanup temporary files in $TempDir, but only if no other instances of this program are running. | ||
- | |||
- | ; Iterate through all via the command line or per 'drag and drop' supplied files | ||
- | $nEdit = CreateGUI($ThisProgramName) ; Create window with info | ||
- | Dim $TotalPages ; Counted pdf pages for each document | ||
- | Dim $tmp | ||
- | Dim $GetFileName | ||
- | Dim $LandscapePages[1] ; Array which holds per page landscape or portrait rotation | ||
- | Dim $PageFitsExact[1] ; Array which holds per page whether it is exactly a4 dimension | ||
- | Dim $FileListArray = SortIfArrayContainsOnlyTiff(GetFileListArray($CmdLine[0])) | ||
- | Const $isPDF = (GetExtension($FileListArray[1]) == $pdf) ; check if first (and thus all the rest as well) file is pdf file. True means all the supplied files are pdf. | ||
- | ; differentiate below between supplied tiff or pdf files. The same code can't be simply used for either tiff or pdf files, since it contains many optimalizations specifically for pdf | ||
- | If $isPDF Then | ||
- | For $i = 1 to UBound($FileListArray)-1 | ||
- | $GetFileName = $FileListArray[$i] | ||
- | GUICtrlSetData($nEdit, | ||
- | GUICtrlSetData($nEdit, | ||
- | GUICtrlSetData($nEdit, | ||
- | $TotalPages = Number(CountPdfPages($GetFileName, | ||
- | If $TotalPages == 0 Then ; pdf file contains 0 pages (means wrong type of file) | ||
- | GUICtrlSetData($nEdit, | ||
- | Else | ||
- | GUICtrlSetData($nEdit, | ||
- | ProcessPages($TotalPages, | ||
- | EndIf | ||
- | Next | ||
- | Else ; process below tiff files | ||
- | GUICtrlSetData($nEdit, | ||
- | $TotalPages = UBound($FileListArray)-1 ; number of suppplied tif files. | ||
- | GUICtrlSetData($nEdit, | ||
- | ProcessPages($TotalPages, | ||
- | EndIf | ||
- | |||
- | Exit | ||
- | |||
- | ; ###################################################################################################### | ||
- | ; # Below are functions | ||
- | ; ###################################################################################################### | ||
- | ; | ||
- | ; Receives the amount of arguments, create a list of files to process. As such Array[0] contains the | ||
- | ; number of supplied files and check if this program is invoked through Scite. | ||
- | Func GetFileListArray(Const $count) | ||
- | If @Compiled <> 0 Then | ||
- | If $count == 0 Then ShowError($_ERROR_ShowHelp) ; number of parameters | ||
- | Return $CmdLine | ||
- | Else ; When invoking this program from within the Scite compiler, use some preset variables for which file to use | ||
- | Local $dbg=$tif ; Choose either $tif or $pdf | ||
- | If $dbg == $pdf Then | ||
- | Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | Else | ||
- | ; Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | Local $FileNames = StringSplit(" | ||
- | ; Local $FileNames = StringSplit(" | ||
- | EndIf | ||
- | Return $FileNames ; return amount of files. | ||
- | EndIf | ||
- | EndFunc | ||
- | |||
- | Func parseCmdOptions(Const $cmdstrFull, | ||
- | Local $cmdstr = StripExtension(StringRegExpReplace($cmdstrFull, | ||
- | Local $cmdpos = stringlen($cmdstr) | ||
- | If ($cmdpos> | ||
- | Do | ||
- | Local $cmds = "" | ||
- | Do | ||
- | $cmdchr = stringmid($cmdstr, | ||
- | If ($cmdchr <> $_OptionChr) Then $cmds = $cmdchr & $cmds | ||
- | $cmdpos = $cmdpos - 1 | ||
- | Until (($cmdpos == 0) Or ($cmdchr == $_OptionChr)) | ||
- | If ($cmdchr == $_OptionChr) Then | ||
- | Switch (StringLower(StringLeft($cmds, | ||
- | Case ' | ||
- | If (StringLen($cmds) == 1) Then | ||
- | $cmdOptions[$_QuadPages] = True | ||
- | EndIf | ||
- | Case ' | ||
- | If ((StringLen($cmds) == 4) Or (StringLen($cmds) == 5)) Then ; Allow 3 and 4 digits numbers, like 300 or 1200 | ||
- | If (StringRegExp(StringTrimLeft($cmds, | ||
- | $cmdOptions[$_Resolution] = Int(Number(StringTrimLeft($cmds, | ||
- | EndIf | ||
- | EndIf | ||
- | Case Else | ||
- | EndSwitch | ||
- | EndIf | ||
- | Until ($cmdpos == 0) | ||
- | EndIf | ||
- | EndFunc | ||
- | |||
- | ; Convert accurately a single page from a pdf file into a bitmap tif | ||
- | ; For each page: | ||
- | ; | ||
- | ; | ||
- | ; | ||
- | ; When gswin32c outputs error text, indicate with 1, otherwise 0 | ||
- | ; | ||
- | ; | ||
- | ; If HiResBoundingBox(lower left x + upper right x, lower left y + upper right y) < BoundingBox(lower left x + upper right x, lower left y + upper right y) Then | ||
- | ; If -1 < Pixel Error < 1 Then | ||
- | ; | ||
- | ; EndIf | ||
- | ; Else | ||
- | ; gswin32c -sDEVICE=tiffgray -r300 -dNOPAUSE -dQUIET -dBATCH -dAutoFilterGrayImages=false -dGrayImageFilter=/ | ||
- | ; IM_Get_Image_Dimension() | ||
- | ; If -1 < Pixel Error < 1 Then | ||
- | ; If IM_Get_PDF_BoundingBox() == 595x842 OR IM_Get_PDF_BoundingBox() == 842x595 Then | ||
- | ; A4Quantization=True | ||
- | ; EndIf | ||
- | ; EndIf | ||
- | ; EndIf | ||
- | ; If A4Quantization=True Then | ||
- | ; gswin32c -sDEVICE=tiffg4 -r300 (-g2480x3508|-g3508x2480) -dMaxStripSize=8192 -dFirstPage=1 -dLastPage=1 -sOutputFile=output.tif input | ||
- | ; EndIf | ||
- | ; | ||
- | Func ExtractPageAsTif(Const $GetFileName, | ||
- | Local $tmpbase = $tempname & " | ||
- | Local $GSResults[9], | ||
- | Local $x, $y, $xx, $yy, $quantize, $command | ||
- | Local $pagedims[2] ; String holding page dimensions. With a4 at 300 dpi, it is 2480x3508, with landscape 3508x2480 | ||
- | |||
- | $GSResults = GS_Get_PDF_BoundingBoxes($GetFileName, | ||
- | If $GSResults[8] Then ShowError($_ERROR_PDF_FileInconsistent) ; If ghostscript threw an error, maybe not all pages can be retreived. Stopping now is the best option. | ||
- | |||
- | ; Check for portrait or landscape orientation. | ||
- | If ($GSResults[0] + $GSResults[2]) < ($GSResults[1] + $GSResults[3]) Then | ||
- | $pagedims[0] = $img_width ; page is portrait | ||
- | $pagedims[1] = $img_height | ||
- | Else | ||
- | $pagedims[0] = $img_height ; page is landscape | ||
- | $pagedims[1] = $img_width | ||
- | EndIf | ||
- | |||
- | ; Check if quantization with 1 pixel necessary | ||
- | If ($GSResults[4] + $GSResults[6]) < ($GSResults[0] + $GSResults[2]) AND _ ; Adding [4] + [6] is not what you would expect when calculating dimensions with coordinates | ||
- | | ||
- | $x = int($cmdOptions[$_Resolution]/ | ||
- | $y = int($cmdOptions[$_Resolution]/ | ||
- | $xx = _Min($x,$y) ; shortest side of image | ||
- | $yy = _Max($x,$y) ; widest side of image | ||
- | If $xx >= ($img_width-$bitmaperror) AND $xx <= ($img_width+$bitmaperror) AND _ ; 1 pixel error at 300 dpi between 2479 and 2481 pixels. | ||
- | $yy >= ($img_height-$bitmaperror) AND $yy <= ($img_height+$bitmaperror) Then | ||
- | |||
- | $quantize = True | ||
- | $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $GetFileName & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | EndIf | ||
- | EndIf | ||
- | |||
- | If Not $quantize Then | ||
- | $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $GetFileName & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | EndIf | ||
- | |||
- | $IMDims = IM_Get_Dims($tmpbase & $tif) | ||
- | If $quantize = False Then | ||
- | $x = $IMDims[0] ; Width in pixels | ||
- | $y = $IMDims[1] ; height in pixels | ||
- | $xx = _Min($x,$y) ; shortest side of image | ||
- | $yy = _Max($x,$y) ; widest side of image | ||
- | If $xx >= ($img_width-$bitmaperror) AND $xx <= ($img_width+$bitmaperror) AND _ ; 1 pixel error at 300 dpi between 2479 and 2481 pixels wide. | ||
- | $yy >= ($img_height-$bitmaperror) AND $yy <= ($img_height+$bitmaperror) Then | ||
- | $quantize = True | ||
- | $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $GetFileName & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | Return $pagedims | ||
- | EndIf | ||
- | EndIf | ||
- | Return $IMDims | ||
- | EndFunc | ||
- | |||
- | ; function to process one or more pages. Will do either pdf or tiff | ||
- | Func ProcessPages(Const $TotalPages, | ||
- | |||
- | If (($q) AND ($TotalPages > 2)) Then GUICtrlSetData($nEdit, | ||
- | local $LandscapePages[$TotalPages], | ||
- | local $FilePagesLargestDim[2] ; Dimensions of the largest page found in a current file. | ||
- | local $FilePagesProperties[2] ; $FilePagesProperties[0]=width in pixels, $FilePagesProperties[1]=height in pixels | ||
- | $FilePagesLargestDim[0]=0 | ||
- | $FilePagesLargestDim[1]=0 | ||
- | Local $j, $tmp | ||
- | For $j = 1 to $TotalPages | ||
- | If ($imgType == $pdf) Then | ||
- | GUICtrlSetData($nEdit, | ||
- | $FilePagesProperties = ExtractPageAsTif($GetFileName, | ||
- | Else | ||
- | GUICtrlSetData($nEdit, | ||
- | $GetFileName = $FileListArray[$j] | ||
- | $FilePagesProperties = IM_Get_Dims($GetFileName) ; get dimensions from tiff file | ||
- | FileCopy($GetFileName, | ||
- | EndIf | ||
- | |||
- | If $FilePagesProperties[0] < $FilePagesProperties[1] Then ; Keep track of page orientation and largest page dimensions | ||
- | $LandscapePages[$j-1] = False | ||
- | If $FilePagesProperties[0] == $img_width AND $FilePagesProperties[1] == $img_height Then | ||
- | $PageFitsExact[$j-1] = True | ||
- | Else | ||
- | $PageFitsExact[$j-1] = False | ||
- | EndIf | ||
- | Else | ||
- | $LandscapePages[$j-1] = True | ||
- | If $FilePagesProperties[0] == $img_height AND $FilePagesProperties[1] == $img_width Then | ||
- | $PageFitsExact[$j-1] = True | ||
- | Else | ||
- | $PageFitsExact[$j-1] = False | ||
- | EndIf | ||
- | EndIf | ||
- | $FilePagesLargestDim[0] = _Max($FilePagesLargestDim[0], | ||
- | $FilePagesLargestDim[1] = _Max($FilePagesLargestDim[1], | ||
- | Next | ||
- | If FileExists($Pdf_ListOfFiles2Proces) Then FileDelete($Pdf_ListOfFiles2Proces) ; Empty this file before adding filenames as text to it. Will be used to merge several pdf files into one. | ||
- | $FHandle = FileOpen($Pdf_ListOfFiles2Proces, | ||
- | Const $ScaleFactor = Calc_scalingfactor($FilePagesLargestDim[0], | ||
- | If $ScaleFactor < 100 Then | ||
- | GUICtrlSetData($nEdit, | ||
- | For $j = 1 to $TotalPages ; Resize image | ||
- | GUICtrlSetData($nEdit, | ||
- | $tmp = $tempname & " | ||
- | ConvertScaleTif2Pdf($tmp, | ||
- | FileWriteLine($FHandle, | ||
- | Next | ||
- | Else | ||
- | For $j = 1 to $TotalPages ; Do not resize image | ||
- | GUICtrlSetData($nEdit, | ||
- | $tmp = $tempname & " | ||
- | ConvertTif2Pdf($tmp, | ||
- | FileWriteLine($FHandle, | ||
- | Next | ||
- | EndIf | ||
- | |||
- | If (($q) AND ($TotalPages > 2) AND (CalcEmptyPages($TotalPages)> | ||
- | For $j = 1 to CalcEmptyPages($TotalPages) | ||
- | $tmp = $tempname & " | ||
- | AddEmptyPage($tmp, | ||
- | FileWriteLine($FHandle, | ||
- | Next | ||
- | EndIf | ||
- | |||
- | FileClose($FHandle) | ||
- | |||
- | MergePDF_BW($Pdf_tmp_FileName, | ||
- | If $isPDF Then | ||
- | FileCopy($Pdf_tmp_FileName, | ||
- | Else | ||
- | FileCopy($Pdf_tmp_FileName, | ||
- | EndIf | ||
- | FileDelete($Pdf_tmp_FileName) | ||
- | IndirectDelete($Pdf_ListOfFiles2Proces) | ||
- | FileDelete($Pdf_ListOfFiles2Proces) | ||
- | EndFunc | ||
- | |||
- | ; find the pdf HiResBoundingBox with ghostscript. GS String: gswin32c -sDEVICE=bbox -dQUIET -dNOPAUSE -dBATCH file | ||
- | Func GS_Get_PDF_BoundingBoxes(Const $PDFFile, Const $j) | ||
- | Local $line, $GSResult[9], | ||
- | $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $PDFFile & $QQ | ||
- | Local $console = Run(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) | ||
- | While 1 | ||
- | Sleep($Delay) | ||
- | $line = StderrRead($console) | ||
- | If @error Then ExitLoop | ||
- | $Result = $line | ||
- | WEnd | ||
- | $GSResult[0] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[1] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[2] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[3] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[4] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[5] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[6] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[7] = Number(StringRegExpReplace($Result, | ||
- | $GSResult[8] = StringRegExp($Result, | ||
- | Return $GSResult | ||
- | EndFunc | ||
- | |||
- | ; find the image dimensions with imagemagick: | ||
- | Func IM_Get_Dims(Const $GetFileName) | ||
- | Local $line, $this_dims[2], | ||
- | Local $Command = " | ||
- | $QQ & " | ||
- | $QQ & " | ||
- | $QQ & $GetFileName & $QQ | ||
- | Local $console = Run(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) | ||
- | While 1 | ||
- | Sleep($Delay) | ||
- | $line = StdoutRead($console) | ||
- | If @error Then ExitLoop | ||
- | $Result = $line | ||
- | WEnd | ||
- | $this_dims[0] = Number(StringRegExpReplace($result, | ||
- | $this_dims[1] = Number(StringRegExpReplace($result, | ||
- | Return $this_dims | ||
- | EndFunc | ||
- | |||
- | Func IM_Get_Type(Const $GetFileName) | ||
- | Local $line, $this_dims[2], | ||
- | Local $Command = " | ||
- | $QQ & " | ||
- | $QQ & " | ||
- | $QQ & $GetFileName & $QQ | ||
- | Local $console = Run(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) | ||
- | While 1 | ||
- | Sleep($Delay) | ||
- | $line = StdoutRead($console) | ||
- | If @error Then ExitLoop | ||
- | $Result = $line | ||
- | WEnd | ||
- | If StringLen($Result) >= 3 Then | ||
- | Return " | ||
- | EndIf | ||
- | Return | ||
- | EndFunc | ||
- | |||
- | |||
- | Func ConvertScaleTif2Pdf(Const $tmpbase, | ||
- | Local $Command, $pagedims[2] | ||
- | $Command = " | ||
- | $QQ & $tmpbase & $tif & $QQ & " " & _ | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & $tif & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | |||
- | If $LandscapePage Then ; make sure page with landscape size has proper dimension | ||
- | $pagedims[0] = $img_height | ||
- | $pagedims[1] = $img_width | ||
- | Else | ||
- | $pagedims[0] = $img_width | ||
- | $pagedims[1] = $img_height | ||
- | EndIf | ||
- | |||
- | $Command = " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & " | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | |||
- | $Command = " | ||
- | $QQ & $tmpbase & $tif & $QQ & " " & _ | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & " | ||
- | $QQ & $tmpbase & " | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | |||
- | If FileExists($tmpbase & " | ||
- | If FileExists($tmpbase & $tif) Then FileDelete($tmpbase & $tif) ; Delete temp file | ||
- | |||
- | $Command = " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & " | ||
- | " | ||
- | $QQ & $tmpbase & $ps & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | If FileExists($tmpbase & " | ||
- | |||
- | $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & $ps & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | If FileExists($tmpbase & $ps) Then FileDelete($tmpbase & $ps) ; Delete temp file | ||
- | EndFunc | ||
- | |||
- | Func AddEmptyPage(Const $tmp,Const $LandscapePage) | ||
- | Local $Command, $tf, $pagedims[2] | ||
- | If $LandscapePage Then ; make sure page with landscape size has proper dimension | ||
- | $pagedims[0] = $img_height | ||
- | $pagedims[1] = $img_width | ||
- | Else | ||
- | $pagedims[0] = $img_width | ||
- | $pagedims[1] = $img_height | ||
- | EndIf | ||
- | $Command = " | ||
- | " | ||
- | " | ||
- | $QQ & $tmp & " | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | |||
- | $Command = " | ||
- | " | ||
- | " | ||
- | $QQ & $tmp & " | ||
- | " | ||
- | $QQ & $tmp & $ps & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | |||
- | If FileExists($tmp & " | ||
- | |||
- | $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $tmp & $ps & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | If FileExists($tmp & $ps) Then FileDelete($tmp & $ps) ; Delete temp file | ||
- | EndFunc | ||
- | |||
- | Func ConvertTif2Pdf(Const $tmpbase, Const $j, Const $PageFitsExactly, | ||
- | Local $Command, $tf, $pagedims[2] | ||
- | |||
- | If $LandscapePage Then ; make sure page with landscape size has proper dimension | ||
- | $pagedims[0] = $img_height | ||
- | $pagedims[1] = $img_width | ||
- | Else | ||
- | $pagedims[0] = $img_width | ||
- | $pagedims[1] = $img_height | ||
- | EndIf | ||
- | |||
- | If $PageFitsExactly Then | ||
- | $Command = " | ||
- | $QQ & $tmpbase & $tif & $QQ & " " & _ | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | $tf = $tmpbase | ||
- | Else | ||
- | $Command = " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & " | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | |||
- | $tf = $tmpbase & " | ||
- | $Command = " | ||
- | $QQ & $tmpbase & $tif & $QQ & " " & _ | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & " | ||
- | $QQ & $tf & $tif & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | |||
- | If FileExists($tmpbase & " | ||
- | If FileExists($tmpbase & $tif) Then FileDelete($tmpbase & $tif) ; Delete temp file | ||
- | |||
- | EndIf | ||
- | |||
- | $Command = " | ||
- | " | ||
- | " | ||
- | $QQ & $tf & $tif & $QQ & " " & _ | ||
- | " | ||
- | $QQ & $tmpbase & $ps & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | If FileExists($tf & $tif) Then FileDelete($tf & $tif) ; Delete temp file | ||
- | |||
- | $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & $tmpbase & $ps & $QQ | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | If FileExists($tmpbase & $ps) Then FileDelete($tmpbase & $ps) ; Delete temp file | ||
- | EndFunc | ||
- | |||
- | ; merge pdf pages into one pdf page and deletes intermediate files | ||
- | Func MergePDF_BW(Const $Pdf_tmp_FileName, | ||
- | Local $Command = " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | $QQ & " | ||
- | RunWait(@ComSpec & " /c " & $Command, @ScriptDir, @SW_HIDE) | ||
- | EndFunc | ||
- | |||
- | ; Find scaling factor to a4 | ||
- | Func Calc_scalingfactor(Const $x1, Const $y1, Const $img_width, Const $img_height) | ||
- | Local $Scale = 1 | ||
- | If _Min($x1, | ||
- | $Scale = $img_width/ | ||
- | EndIf | ||
- | If _Max($x1, | ||
- | $Scale = _Min($img_height/ | ||
- | EndIf | ||
- | Return Int($Scale*100) ; Scalingfactor is between 0 and 100; 100 means no change. | ||
- | EndFunc | ||
- | |||
- | Func CalcEmptyPages($count) | ||
- | Return Abs(BitAND(mod($count+3, | ||
- | EndFunc | ||
- | |||
- | ; Extract file name from path | ||
- | Func RemovePath(Const $OutputFile) | ||
- | If FileExists(RemoveDoubleQuotes($OutputFile)) Then | ||
- | Local $szDrive, $szDir, $szFName, $szExt | ||
- | _PathSplit(RemoveDoubleQuotes($OutputFile), | ||
- | Return $szFName & $szExt | ||
- | Else | ||
- | ShowError(" | ||
- | EndIf | ||
- | EndFunc | ||
- | |||
- | ; This function will remove a trailing slash to a windows file path | ||
- | Func RemoveDoubleQuotes(Const $var) | ||
- | Return StringRegExpReplace($var, | ||
- | EndFunc | ||
- | |||
- | Func ModifyFileName(Const $GetFileName) | ||
- | Local $szDrive, $szDir, $szFName, $szExt | ||
- | _PathSplit($GetFileName, | ||
- | Return | ||
- | EndFunc | ||
- | |||
- | ; Prevent overwriting a file, when it already exists. This function will find the ' | ||
- | Func UniqueFileName(Const $OutputFile) | ||
- | If FileExists(RemoveDoubleQuotes($OutputFile)) Then | ||
- | Local $i = 1 | ||
- | Local $szDrive, $szDir, $szFName, $szExt | ||
- | _PathSplit(RemoveDoubleQuotes($OutputFile), | ||
- | While FileExists($szDrive & $szDir & $szFName & " | ||
- | $i += 1 | ||
- | WEnd | ||
- | Return $szDrive & $szDir & $szFName & " | ||
- | Else | ||
- | Return $OutputFile | ||
- | EndIf | ||
- | EndFunc | ||
- | |||
- | ; This function will add a trailing slash to a windows file path | ||
- | Func AddSlash(Const $var) | ||
- | Return StringRegExpReplace($var, | ||
- | EndFunc | ||
- | |||
- | ; Create GUI window with console like output | ||
- | Func CreateGUI(Const $ThisProgramName) | ||
- | Const $Gui_Xpos = 140 | ||
- | Const $Gui_Ypos = 23 | ||
- | Const $Gui_Width = 518 | ||
- | Const $Gui_Height = 200 | ||
- | Const $Gui_Border = 15 | ||
- | Const $Gui_HeightButton = 20 | ||
- | Const $Gui_WidthButton = 75 | ||
- | Const $Gui_WidthSlider = 20 | ||
- | Opt(" | ||
- | HotKeySet(" | ||
- | GUICreate($Gui_Title, | ||
- | $nEdit = GUICtrlCreateEdit ("", | ||
- | GUICtrlSetBkColor($nEdit, | ||
- | $hButton = GUICtrlCreateButton (" | ||
- | GUICtrlSetOnEvent($hButton, | ||
- | GUISetState() | ||
- | Return $nEdit | ||
- | EndFunc | ||
- | |||
- | ; Strip path and extension | ||
- | Func StripExtension(Const $OutputFile) | ||
- | Local $szDrive, $szDir, $szFName, $szExt | ||
- | _PathSplit(RemoveDoubleQuotes($OutputFile), | ||
- | Return $szDrive & $szDir & $szFName | ||
- | EndFunc | ||
- | |||
- | ; Strip everything but the file extension | ||
- | Func GetExtension(Const $OutputFile) | ||
- | If FileExists(RemoveDoubleQuotes($OutputFile)) Then | ||
- | Local $szDrive, $szDir, $szFName, $szExt | ||
- | _PathSplit(RemoveDoubleQuotes($OutputFile), | ||
- | Return StringLower($szExt) | ||
- | Else | ||
- | ShowError(" | ||
- | EndIf | ||
- | EndFunc | ||
- | |||
- | Func IndirectDelete(Const $Pdf_ListOfFiles2Proces) | ||
- | Local $Handle = FileOpen($Pdf_ListOfFiles2Proces, | ||
- | Local $line | ||
- | While 1 | ||
- | $line = FileReadLine($Handle) | ||
- | If @error = -1 Then ExitLoop | ||
- | If FileExists($line) Then FileDelete($line) ; Delete temp file | ||
- | Wend | ||
- | FileClose($Handle) | ||
- | EndFunc | ||
- | |||
- | ; Find number of PDF pages in document | ||
- | Func CountPdfPages(Const $GetFileName, | ||
- | Local $Command | ||
- | $Command = $QQ & $GetFileName & $QQ & " " & _ ; Use pdf2dsc to find out the number of pages. E.g. %%Pages: 1 | ||
- | $QQ & $tempname & " | ||
- | _RunDos(" | ||
- | $Command = OpenFileAndGrep($tempname & " | ||
- | If FileExists($tempname & " | ||
- | If Not $Command Then Return(0); The supplied file is not a pdf file, in order to skip this file, 0 (pages) will be returned | ||
- | Return(Number(StringReplace($Command, | ||
- | EndFunc | ||
- | |||
- | ; Check if first array item is a tiff file, if yes, check all other files for validity as well. If all are tiff files, sort them. | ||
- | ; Sort tif files only on filename, without path | ||
- | Func SortIfArrayContainsOnlyTiff(Const $FileListArray) | ||
- | Local $testfull = False ; False means file will only be tested for occurence of .tif or .tiff in filename. True means each file will be tested by ImageMagick (This is slow) | ||
- | If $testfull Then | ||
- | if IM_Get_Type($FileListArray[1]) == $pdf Then Return $FileListArray ; Test at least the first file comprehensive. | ||
- | Else | ||
- | if StringLeft(GetExtension($FileListArray[1]), | ||
- | EndIf | ||
- | Local $i = 1 | ||
- | Local $ft | ||
- | Local $temp1[UBound($FileListArray)-1][2] | ||
- | Local $temp2[UBound($FileListArray)] | ||
- | If $testfull Then GUICtrlSetData($nEdit, | ||
- | Do | ||
- | If $testfull Then | ||
- | GUICtrlSetData($nEdit, | ||
- | $ft = IM_Get_Type($FileListArray[$i]) ; Comprehensive test | ||
- | GUICtrlSetData($nEdit, | ||
- | Else | ||
- | $ft = StringLeft(GetExtension($FileListArray[$i]), | ||
- | EndIf | ||
- | If $ft <> $tif Then ShowError(" | ||
- | $temp1[$i-1][0] = RemovePath($FileListArray[$i]) | ||
- | $temp1[$i-1][1] = $FileListArray[$i] | ||
- | $i = $i + 1 | ||
- | Until | ||
- | _ArraySort($temp1) | ||
- | ; $temp2[0] = UBound($temp1) | ||
- | For $i=1 to UBound($temp1) | ||
- | $temp2[$i] = $temp1[$i-1][1] | ||
- | Next | ||
- | Return $temp2 | ||
- | EndFunc | ||
- | |||
- | ; Opens a file and returns a line which contains a grep alike specified keyword | ||
- | Func OpenFileAndGrep(Const $OFAG_path, | ||
- | Local $OFAG_file = FileOpen($OFAG_path, | ||
- | Local $OFAG_result = FileRead($OFAG_file) | ||
- | FileClose($OFAG_file) | ||
- | |||
- | If $OFAG_result = "" | ||
- | Return | ||
- | Else | ||
- | Local $OFAG_q = "" | ||
- | Local $OFAG_stdinArray = StringSplit($OFAG_result, | ||
- | Local $OFAG_i | ||
- | For $OFAG_i In $OFAG_stdinArray | ||
- | If StringInStr($OFAG_i, | ||
- | $OFAG_q &= $OFAG_i | ||
- | ExitLoop | ||
- | EndIf | ||
- | Next | ||
- | EndIf | ||
- | return $OFAG_q | ||
- | EndFunc | ||
- | |||
- | ; Cleanup temporary files in $TempDir, but only if no other instances of this program are running. | ||
- | Func GarbageControl(Const $ThisProgramName) | ||
- | Local $i | ||
- | Local $count = 0 | ||
- | Local $list = ProcessList() | ||
- | For $i = 1 to $list[0][0] | ||
- | If $list[$i][0] = $ThisProgramName & " | ||
- | Next | ||
- | If $count == 1 Then | ||
- | If FileExists(@TempDir & " | ||
- | EndIf | ||
- | EndFunc | ||
- | |||
- | ; Check MS dependencies and set environment variables for Imagemagick, | ||
- | Func CheckAndSetEnv() | ||
- | If Not Find_MS_Visual_C_PlusPlus_2008_SP1_Redist() Then ShowError($_ERROR_MSVisualCPlusPlus2008RedistNotInstalled) | ||
- | If Not FileExists(Find_imagemagick_Path(" | ||
- | ; If Not FileExists(@SystemDir & " | ||
- | If Not EnvPathExists(Find_Ghostscript_Path($Ghostscript_RegPath," | ||
- | If Not EnvPathExists(Find_imagemagick_Path($imagemagick_RegPath," | ||
- | ; If Not ObjectIsRegistered(" | ||
- | EndFunc | ||
- | |||
- | ; Find Microsoft Visual C++ 2008 SP1 Redistributable Package | ||
- | Func Find_MS_Visual_C_PlusPlus_2008_SP1_Redist() | ||
- | Local $var | ||
- | $var = RegRead(" | ||
- | If @error <> 0 Or $var == "" | ||
- | Return True | ||
- | EndFunc | ||
- | |||
- | ; This function makes sure that the to be added $EnvironmentVariablePath is only added once to the environment path. For this it differentiates between Ghostscript and ImageMagick | ||
- | Func SetEnvPath(Const $EnvVarApplication) | ||
- | If StringRight(EnvGet(" | ||
- | Local $i | ||
- | Local $SplitEnvVarApplication = StringSplit($EnvVarApplication,";" | ||
- | If @error == 1 Then | ||
- | EnvSet(" | ||
- | Else | ||
- | For $i = 1 To $SplitEnvVarApplication[0] | ||
- | If Not StringInStr(EnvGet(" | ||
- | Next | ||
- | EndIf | ||
- | EndFunc | ||
- | |||
- | ; This function checks whether the (part of the) $EnvVarApplication already exists in the %PATH% environment. | ||
- | Func EnvPathExists(Const $EnvVarApplication) | ||
- | Local $i | ||
- | Local $found = True | ||
- | Local $SplitEnvVarApplication = StringSplit($EnvVarApplication,";" | ||
- | If @error == 1 Then | ||
- | If StringInStr(EnvGet(" | ||
- | Else | ||
- | For $i = 1 To $SplitEnvVarApplication[0] | ||
- | If Not StringInStr(EnvGet(" | ||
- | Next | ||
- | EndIf | ||
- | Return $found | ||
- | EndFunc | ||
- | |||
- | ; Find Ghostscript Path | ||
- | Func Find_Ghostscript_Path(Const $Ghostscript_RegHive, | ||
- | Local $var | ||
- | Local $var_read | ||
- | Local $i = 1 | ||
- | Local $GhostscriptVersion | ||
- | Local $GhostscriptPath | ||
- | Local $GhostscriptFound = False | ||
- | Local $GhostscriptPathFound = False | ||
- | |||
- | While 1 | ||
- | $var = RegEnumKey($Ghostscript_RegHive, | ||
- | If @error <> 0 Then ExitLoop | ||
- | If StringRegExp($var," | ||
- | $GhostscriptVersion = String($var) | ||
- | $GhostscriptFound = True | ||
- | EndIf | ||
- | $i += 1 | ||
- | WEnd | ||
- | |||
- | $i = 1 | ||
- | If $GhostscriptFound Then | ||
- | While 1 | ||
- | $var = RegEnumVal($Ghostscript_RegHive & " | ||
- | If @error <> 0 Then ExitLoop | ||
- | If $var == $Ghostscript_EnvKey Then | ||
- | $GhostscriptPath = RegRead($Ghostscript_RegHive & " | ||
- | $GhostscriptPath &= StringRegExpReplace($GhostscriptPath, | ||
- | $GhostscriptPathFound = True | ||
- | ExitLoop | ||
- | EndIf | ||
- | $i += 1 | ||
- | WEnd | ||
- | EndIf | ||
- | |||
- | If $GhostscriptPathFound Then | ||
- | Return $GhostscriptPath | ||
- | Else | ||
- | ShowError ($_ERROR_CannotFindGhostscript) | ||
- | EndIf | ||
- | Return | ||
- | EndFunc | ||
- | |||
- | ; Find imagemagick Path | ||
- | Func Find_imagemagick_Path(Const $imagemagick_RegHive, | ||
- | Local $var | ||
- | $var = RegRead($imagemagick_RegHive, | ||
- | If @error <> 0 Or $var == "" | ||
- | Return $var | ||
- | EndFunc | ||
- | |||
- | ; Find if object is already registered | ||
- | Func ObjectIsRegistered(Const $Obj_RegHive, | ||
- | Local $var | ||
- | $var = RegRead($Obj_RegHive, | ||
- | If @error <> 0 Or $var <> " | ||
- | Return True | ||
- | EndFunc | ||
- | |||
- | ; Cancel button had been pressed. A few cleanup steps should take place. | ||
- | Func CancelButton() | ||
- | GUIDelete() | ||
- | If FileExists($tempname & " | ||
- | Exit | ||
- | EndFunc | ||
- | |||
- | ; Show related error, try to terminate program properly | ||
- | Func ShowError(Const $_ERROR_Number) | ||
- | Switch $_ERROR_Number | ||
- | ; Case $_ERROR_MissingImageMagickObject | ||
- | ; | ||
- | ; | ||
- | Case $_ERROR_PdfInputFileIsNotValid | ||
- | MsgBox(0," | ||
- | " | ||
- | Case $_ERROR_ShowHelp | ||
- | MsgBox(0," | ||
- | " | ||
- | " | ||
- | " | ||
- | StringRegExpReplace(@ScriptName, | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | Case $_ERROR_PdfImageSizeTooLarge | ||
- | MsgBox(0," | ||
- | " | ||
- | Case $_ERROR_CannotFindGhostscript | ||
- | MsgBox(0," | ||
- | " | ||
- | " | ||
- | " | ||
- | Case $_ERROR_imagemagickNotInstalled | ||
- | MsgBox(0," | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | Case $_ERROR_MSVisualCPlusPlus2008RedistNotInstalled | ||
- | MsgBox(0," | ||
- | " | ||
- | " | ||
- | " | ||
- | Case $_ERROR_PDF_FileInconsistent | ||
- | MsgBox(0," | ||
- | " | ||
- | " | ||
- | " | ||
- | " | ||
- | Case Else | ||
- | MsgBox(0," | ||
- | EndSwitch | ||
- | Exit | ||
- | EndFunc</ |