Given the OP is primarily interested in file size, here’s another approach. In this case you pass not only a maximum height/width, but also a target file size in bytes. The script will rescale the pic and try with a low compression factor of 0.8 (scale is 0.0 to 1.0). If the result was too big, it will reduce the compression factor by 10% and try again, repeating until the file size is below the limit, or the compression factor hits 0.2 (point of diminishing returns).
use scripting additions
use framework "Foundation"
use framework "AppKit"
on resizedJpegFromPath:imagePath maxHeightOrWidth:maxDim targetBytes:maxBytes
set imagePath to current application's NSString's stringWithString:imagePath
set outPath to (imagePath's stringByDeletingPathExtension()'s stringByAppendingString:"-out")
set outPath to outPath's stringByAppendingPathExtension:"jpg"
-- Get the contents of the passed picture
set theImageRep to current application's NSBitmapImageRep's imageRepWithContentsOfFile:imagePath -- load the file
set theClip to current application's NSPasteboard's generalPasteboard()
-- Extract its original size
set oldHeight to theImageRep's pixelsHigh()
set oldWidth to theImageRep's pixelsWide()
if oldWidth > oldHeight then
set theWidth to maxDim
set theHeight to oldHeight * maxDim / oldWidth
else
set theHeight to maxDim
set theWidth to oldWidth * maxDim / oldHeight
end if
set newRep to (current application's NSBitmapImageRep's alloc()'s initWithBitmapDataPlanes:(missing value) pixelsWide:theWidth pixelsHigh:theHeight bitsPerSample:8 samplesPerPixel:4 hasAlpha:yes isPlanar:false colorSpaceName:(current application's NSDeviceRGBColorSpace) bytesPerRow:0 bitsPerPixel:32)
-- store the existing graphics context
current application's NSGraphicsContext's saveGraphicsState()
-- set graphics context to new context based on the new bitmapImageRep
current application's NSGraphicsContext's setCurrentContext:(current application's NSGraphicsContext's graphicsContextWithBitmapImageRep:newRep)
theImageRep's drawInRect:{origin:{x:0, y:0}, |size|:{width:theWidth, height:theHeight}} fromRect:(current application's NSZeroRect) operation:(current application's NSCompositeSourceOver) fraction:1.0 respectFlipped:false hints:(missing value)
-- restore state
current application's NSGraphicsContext's restoreGraphicsState()
set compFactor to 0.8 -- starting compression value
set compMax to 0.2 -- compression limit
repeat
set theData to newRep's representationUsingType:(current application's NSJPEGFileType) |properties|:{NSImageCompressionFactor:compFactor}
if compFactor > compMax and theData's |length|() > maxBytes then
-- too big, so try with more compression
set compFactor to compFactor * 0.9
else -- give up
exit repeat
end if
end repeat
theData's writeToFile:outPath atomically:true
end resizedJpegFromPath:maxHeightOrWidth:targetBytes:
set anImage to choose file of type {"public.png", "public.tiff", "public.jpeg"}
my resizedJpegFromPath:(POSIX path of anImage) maxHeightOrWidth:800 targetBytes:100000