The script included below crops all pages of a PDF document and creates a new PDF with the cropped pages. To test this script, open it to a script editor and run.
The user is prompted to enter a crop rectangle, which is in points and consists of an x coordinate, y coordinate, width, and height. Just as a point of information, there are 72 points in an inch and 2.83 points in a millimeter.
It should be noted that this script does not crop a PDF page in the sense that a bitmap image can be cropped. It instead sets the PDF’s crop box, which generally defines the area of the PDF that will be displayed and printed by a PDF viewer application. This is what happens when a PDF is cropped by the Preview application.
-- revised 2022.11.19
use framework "Foundation"
use framework "Quartz"
use scripting additions
on main()
set sourceFile to POSIX path of (choose file with prompt "Choose a PDF file to crop" of type {"pdf"})
set sourceFile to current application's |NSURL|'s fileURLWithPath:sourceFile
set theDocument to (current application's PDFDocument's alloc()'s initWithURL:sourceFile)
set {x, y, w, h} to getBounds(sourceFile, theDocument)
set cropRectangle to text returned of (display dialog "Enter the crop rectangle consisting of the x coordinate, y coordinate, width, and height." default answer (x as text) & " " & y & " " & w & " " & h with title "PDF Crop" buttons {"Cancel", "Crop"} cancel button 1 default button 2)
set cropRectangle to current application's NSString's stringWithString:cropRectangle
set cropRectangle to ((cropRectangle's componentsSeparatedByString:space)'s valueForKey:"integerValue") as list
try
cropPDF(sourceFile, theDocument, cropRectangle)
on error
display alert "The PDF could not be cropped" message "Normally this occurs when the PDF cannot be read or when the crop rectangle lacks necessary data" as critical
error number -128
end try
end main
on getBounds(sourceFile, theDocument)
set aPage to (theDocument's pageAtIndex:0)
set {{x, y}, {w, h}} to (aPage's boundsForBox:(current application's kPDFDisplayBoxMediaBox))
return {x as integer, y as integer, w as integer, h as integer}
end getBounds
on cropPDF(sourceFile, theDocument, cropRectangle)
set {a2, b2, c2, d2} to cropRectangle
set sourceFolder to sourceFile's URLByDeletingLastPathComponent
set sourceFileName to (sourceFile's URLByDeletingPathExtension())'s lastPathComponent()
set targetFileName to sourceFileName's stringByAppendingString:" (cropped).pdf"
set targetFile to sourceFolder's URLByAppendingPathComponent:targetFileName
set sourcePageCount to theDocument's pageCount()
repeat with i from 0 to (sourcePageCount - 1)
set aPage to (theDocument's pageAtIndex:(i))
set {{a1, b1}, {c1, d1}} to (aPage's boundsForBox:(current application's kPDFDisplayBoxMediaBox))
set pageSize to {{a2, (d1 - b2 - d2)}, {c2, d2}}
(aPage's setBounds:pageSize forBox:(current application's kPDFDisplayBoxCropBox))
(theDocument's removePageAtIndex:i)
(theDocument's insertPage:aPage atIndex:i)
end repeat
theDocument's writeToURL:targetFile
end cropPDF
main()