I looked at a script written by Fredrik71 in the thread linked below. I was curious how this script compared with the script included above and with a script that uses the sips utility. My test image was a photo taken with a Pixel 4a phone, but I ran additional tests with many other images from various sources. The goal was to reduce the width of the photo to 1000 pixels.
The results were:
SCRIPT - FILE SIZE - TIMING RESULT
AppKit - 102KB - 52 milliseconds
CoreImage 113KB - 78 milliseconds
Sips - 160KB - 87 milliseconds
None of the above seems very significant, but I was surprised that the image created with the AppKit script was degraded as compared with the original with a somewhat dark cast and a lack of definition. The other scripts returned photos that were not at all degraded. Perhaps my implementation of the AppKit script is erroneous in some respect. It’s important to note that the AppKit and CoreImage scripts do not include Exif and other significant metadata in the newly-created images.
Most users are best advised to use sips or Image Events or one of the many utilities that will resize images. For learning purposes, I find this topic of interest.
The AppKit script is:
-- Revised 2021.10.18 to fix lack of definition and dark color cast
use framework "AppKit"
use framework "Foundation"
use scripting additions
on main()
set sourceFile to POSIX path of (choose file)
set targetFile to POSIX path of ((path to desktop as text) & "Reduced Image.jpg")
set {existingWidth, existingHeight} to getImageSize(sourceFile)
set newWidth to 1000
set newHeight to round ((newWidth / existingWidth) * existingHeight)
set sourceImage to current application's NSImage's alloc()'s initWithContentsOfFile:sourceFile
set aRep to current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:newWidth pixelsHigh:newHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:true isPlanar:false colorSpaceName:(current application's NSDeviceRGBColorSpace) bytesPerRow:0 bitsPerPixel:0
set newSize to {width:newWidth, height:newHeight}
aRep's setSize:newSize
current application's NSGraphicsContext's saveGraphicsState()
set theContext to current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:aRep
current application's NSGraphicsContext's setCurrentContext:theContext
theContext's setShouldAntialias:false -- change to suit
theContext's setImageInterpolation:(current application's NSImageInterpolationDefault) -- change to suit
sourceImage's drawInRect:(current application's NSMakeRect(0, 0, newWidth, newHeight)) fromRect:(current application's NSZeroRect) operation:(current application's NSCompositeCopy) fraction:(1.0)
current application's NSGraphicsContext's restoreGraphicsState()
set theRep to aRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:0.5, NSImageProgressive:false}
theRep's writeToFile:targetFile atomically:true
end main
on getImageSize(theFile)
set theImage to current application's NSBitmapImageRep's imageRepWithContentsOfFile:theFile
set pixelWidth to theImage's pixelsWide()
set pixelHeight to theImage's pixelsHigh()
return {pixelWidth, pixelHeight}
end getImageSize
main()
The CoreImage script is:
use framework "Foundation"
use framework "CoreImage"
use scripting additions
on main()
set sourceFile to "/Users/Robert/Working/Test Photo.jpg"
set targetFile to POSIX path of ((path to desktop as text) & "Reduced CoreImage.jpg")
set targetWidth to 1000
set sourceFile to current application's |NSURL|'s fileURLWithPath:sourceFile
set sourceImage to current application's CIImage's imageWithContentsOfURL:sourceFile options:(missing value)
set {sourceWidth, sourceHeight} to {item 1 of item 2 of sourceImage's extent(), item 2 of item 2 of sourceImage's extent()}
set imageScale to targetWidth / sourceWidth
set resizeFilter to current application's CIFilter's filterWithName:"CILanczosScaleTransform" withInputParameters:{inputImage:sourceImage, inputScale:imageScale, inputAspectRatio:1.0}
set outputImage to resizeFilter's outputImage()
set imageRep to current application's NSBitmapImageRep's alloc()'s initWithCIImage:outputImage
set theRep to imageRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:0.5, NSImageProgressive:false}
theRep's writeToFile:targetFile atomically:true
end main
main()
The sips script is:
set sourceFile to "/Users/Robert/Working/Test Photo.jpg"
set targetFile to POSIX path of ((path to desktop as text) & "Reduced Sips.jpg")
do shell script "sips -Z 1000 " & quoted form of sourceFile & " --out " & quoted form of targetFile
Fredrik71’s script can be found at:
https://macscripter.net/viewtopic.php?id=48708