I have a bunch of PDFs containing scans, one image per page.
They have been scanned in RVB, A4 format, 300ppi.
I want to export each image in JPG, grayscale, 150ppi.
Here’s all I’m able to do:
use framework "Foundation"
use framework "AppKit"
use framework "Quartz"
use scripting additions
set folderURL to current application's NSURL's fileURLWithPath:"someFolder"
set pdfURL to current application's NSURL's fileURLWithPath:"somePDF"
set theDoc to current application's PDFDocument's alloc()'s initWithURL:pdfURL
set pageCount to (theDoc's pageCount())
repeat with iPage from 1 to pageCount
set thePage to (theDoc's pageAtIndex:(iPage - 1))
set theData to (thePage's dataRepresentation())
set theImage to (current application's NSImage's alloc()'s initWithData:theData)
set theTiff to theImage's TIFFRepresentation()
set theBitmap to (current application's NSBitmapImageRep's imageRepWithData:theTiff)
set theJpeg to (theBitmap's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:0.6, NSImageProgressive:false})
set destURL to (folderURL's URLByAppendingPathComponent:("test" & iPage & ".jpg"))
set theResult to (theJpeg's writeToURL:destURL atomically:true)
end repeat
It can probably be done more efficiently than this, but it should get you started:
use framework "Foundation"
use framework "AppKit"
use framework "Quartz"
use scripting additions
set folderURL to current application's |NSURL|'s fileURLWithPath:"/Users/shane/Desktop/"
set pdfURL to current application's |NSURL|'s fileURLWithPath:"/Users/shane/Desktop/Test.pdf"
set theDoc to current application's PDFDocument's alloc()'s initWithURL:pdfURL
set pageCount to (theDoc's pageCount())
repeat with iPage from 1 to pageCount
set thePage to (theDoc's pageAtIndex:(iPage - 1))
set theData to (thePage's dataRepresentation())
set pdfImageRep to (current application's NSPDFImageRep's imageRepWithData:theData)
set theBounds to pdfImageRep's |bounds|()
set aWidth to (current application's NSWidth(theBounds)) / 72 * 150
set aHeight to (current application's NSHeight(theBounds)) / 72 * 150
-- resize by creating new bitmap and drawing into it
set newBitmap to (current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:aWidth pixelsHigh:aHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:true isPlanar:false colorSpaceName:(current application's NSCalibratedRGBColorSpace) bytesPerRow:0 bitsPerPixel:0)
current application's NSGraphicsContext's saveGraphicsState()
set theContext to (current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:newBitmap)
(current application's NSGraphicsContext's setCurrentContext:theContext)
-- set the active color to white
current application's NSColor's whiteColor()'s |set|()
-- fill the bitmapImageRep with white
current application's NSRectFill({origin:{x:0, y:0}, |size|:{width:aWidth, height:aHeight}})
(theContext's setShouldAntialias:true)
(theContext's setImageInterpolation:(current application's NSImageInterpolationDefault))
(pdfImageRep's drawInRect:(current application's NSMakeRect(0, 0, aWidth, aHeight)) fromRect:(current application's NSZeroRect) operation:(current application's NSCompositeSourceOver) fraction:(1.0) respectFlipped:true hints:(missing value))
current application's NSGraphicsContext's restoreGraphicsState()
-- convert to greyscale
set targetSpace to current application's NSColorSpace's deviceGrayColorSpace()
set newBitmap to (newBitmap's bitmapImageRepByConvertingToColorSpace:targetSpace renderingIntent:(current application's NSColorRenderingIntentDefault))
-- save
set theJpeg to (newBitmap's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:0.6, NSImageProgressive:false})
set destURL to (folderURL's URLByAppendingPathComponent:("test" & iPage & ".jpg"))
set theResult to (theJpeg's writeToURL:destURL atomically:true)
end repeat
Not exactly, although you could try that approach, setting a value of missing value for NSImageColorSyncProfileData.
I was thinking of setting the colorSpace property of the NSBitmapImageRep.
Try inserting something like this before the jpeg part:
set theCIImage to (current application's CIImage's alloc()'s initWithBitmapImageRep:newBitmap)
set theCIFilter to (current application's CIFilter's filterWithName:"CIUnsharpMask" withInputParameters:{inputRadius:5.0, inputIntensity:0.9}) -- your values of choice
(theCIFilter's setValue:theCIImage forKey:(current application's kCIInputImageKey))
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set newBitmap to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)
In fact, you could probably do the scaling and conversion to greyscale with CIFilters too:
set theCIImage to (current application's CIImage's alloc()'s initWithBitmapImageRep:newBitmap)
set theCIFilter to (current application's CIFilter's filterWithName:"CIUnsharpMask" withInputParameters:{inputRadius:5.0, inputIntensity:0.9, inputImage:theCIImage}) -- your values of choice
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set theCIFilter to (current application's CIFilter's filterWithName:"CIPhotoEffectMono" withInputParameters:{inputImage:theCIImage})
set theCIImage to (theCIFilter's valueForKey:(current application's kCIOutputImageKey))
set newBitmap to (current application's NSBitmapImageRep's alloc()'s initWithCIImage:theCIImage)