This may not be that useful considering System Events gives quite a few image manipulation tools, but it does not allow you to choose both height and width when resizing. Here’s a function that lets you do it:
use AppleScript version "2.4"
use framework "Foundation"
use framework "AppKit"
use scripting additions
its resizeImageAtPath:"/Users/tneison/Desktop/anInputImg.png" outputTo:"/Users/tneison/Desktop/output.png" width:500.0 height:500.0
on resizeImageAtPath:imgPath outputTo:outputPath width:newWidth height:newHeight
set sourceImg to current application's NSImage's alloc()'s initWithContentsOfFile:imgPath
set scaledImg to current application's NSImage's alloc()'s initWithSize:(current application's NSMakeSize(newWidth, newHeight))
scaledImg's lockFocus()
set sourceImg's size to (current application's NSMakeSize(newWidth, newHeight))
set (current application's NSGraphicsContext's currentContext())'s imageInterpolation to 3
sourceImg's drawInRect:(current application's NSMakeRect(0.0, 0.0, newWidth, newHeight))
scaledImg's unlockFocus()
set outputPNGData to (current application's NSBitmapImageRep's imageRepWithData:(scaledImg's TIFFRepresentation))'s representationUsingType:(current application's NSPNGFileType) |properties|:(current application's NSDictionary's dictionary())
outputPNGData's writeToFile:outputPath atomically:true
end resizeImageAtPath:outputTo:width:height:
set sourceImg's size to (current application's NSMakeSize(newWidth, newHeight))
set (current application's NSGraphicsContext's currentContext())'s imageInterpolation to 3
current application's NSGraphicsContext's currentContext())'s setImageInterpolation:(current application's NSImageInterpolationHigh)
I think it’s generally preferable to use enums rather than raw numbers, for the sake of readability.
FWIW, Objective-C didn’t used to have such things as properties. Instead, you declared an instance variable, and then you wrote two accessor methods for it: the getter, which generally had the same name as the variable (although boolean values were often accessed via isVariable), and the setter, which took the form of setVariable:. The code within these methods would handle the memory management for the value, which would vary depending on the type of value being stored, and the idea was access would be all be done safely via the accessors.
This meant a lot of boilerplate code, and it was also easy to get the memory management code wrong, often resulting in hard-to-trace crashes. Properties were introduced as a replacement; they do what the old code did, reducing both the amount of code that needed to be written, and the possibility of errors. But they still effectively implement the same stuff under the hood.
And lots of other stuff relies on this naming pattern, including application scripting. So if you look at an .sdef file for an app like Mail, you will see the color property is defined as having a cocoa key of foregroundColor. That just tells Cocoa scripting to use -foregroundColor as getter and -setForegroundColor: as setter.
Actually that is really interesting. The setters don’t appear in the Apple documentations for NSImage so I would have had no way of knowing (unless, I suppose, I knew anything at all about Objective C). I was only able to write this ASOC image resizer because I first saw it written in Swift.
Would you say this is the case most of the time?
On a separate note. I was never able to get the NSImage method drawAtPoint:fromRect:operation:fraction: to work. I wanted to use it to do some compositing.
This is what I attempted:
I see what you mean about setting properties directly not being reliable. When I subbed in drawAtPoint:, it succeed but the image was garbled. When I changed to setSize:, it worked again.
I think I could do overlays and compositing now. However, I haven’t a reason to do it…