There are similar answers already on here (like this one), but not with exactly what I want to accomplish. I would like to create an AppleScript that takes a chosen folder and application (or image file), scales the icon of the application/image down to maybe 60% of normal, layers that scaled icon onto the folder icon in a chosen position, and then pastes the resulting layered icon back onto the chosen folder. For example, something like this.
I've been working based on the other solution I linked to, but I don't know much AppleScript, and I don't know enough about Foundation and AppKit to even begin with that. What I've tried so far with plain AppleScript hasn't worked, and I'm not sure I can even accomplish what I want with plain AppleScript (particularly the layering part, I believe). Any help greatly appreciated.
In addition to image editing applications such as Gimp, there are a variety of applications available that will overlay an image onto a folder. If you just wanted to use a script to do it yourself, AppleScriptObjC can be used to access methods from various Cocoa classes such as NSImage.
The following script gets a generic folder icon image from the system resources and an overlay image from a file or application icon. The image is then scaled and composited onto the folder image and set as the icon for a folder or saved to a file on the desktop. Note that the Finder mostly creates its own composite icons, so they may be different than the system defaults.
A folder icon can be set programmatically, but I have found that the scale and location offsets of the application icons usually need to be adjusted a little, as the overlay image may have different padding or arrangement within its bounds. An image file can also be dragged to a Finder Get Info window to set the icon, so the default is to save the output image to a file.
use AppleScript version "2.7" -- High Sierra (10.13) or later for newer enumerations
use framework "Foundation"
use scripting additions
property iconResources : POSIX path of (path to library folder from system domain) & "CoreServices/CoreTypes.bundle/Contents/Resources/" -- system icons
property baseSize : 1024 -- base image size (icons are square with maximum size 1024)
property scale : 0.55 -- scale of overlayed image (adjust as desired)
property setIcon : false -- set folder icon or save to file
on run -- overlay an image onto a folder icon
set baseImage to getBaseImage(iconResources & "GenericFolderIcon.icns") -- or whatever icon image
baseImage's setSize:{baseSize, baseSize}
set overlayImage to getOverlayImage(choose file with prompt "Choose an application or overlay image:")
set scaledSize to baseSize * scale
overlayImage's setSize:{scaledSize, scaledSize}
set offsetX to (baseSize - scaledSize) / 2 -- center (adjust as needed)
set offsetY to (baseSize - scaledSize) / 2 - 50 -- shift down from center (adjust as needed)
baseImage's lockFocus() -- set drawing context
overlayImage's drawAtPoint:{offsetX, offsetY} fromRect:(current application's NSZeroRect) operation:(current application's NSCompositingOperationSourceOver) fraction:1.0
baseImage's unlockFocus()
output(baseImage)
end run
to getBaseImage(imagePath)
set image to readImageFromFile(imagePath)
if image is missing value then error "Base image was not found."
return image
end getBaseImage
to getOverlayImage(imageFile)
tell application "Finder" to if (kind of imageFile is "Application") then
set image to current application's NSWorkspace's sharedWorkspace's iconForFile:(POSIX path of imageFile)
else
set image to my readImageFromFile(POSIX path of imageFile)
end if
if image is missing value then error "Overlay image was not found."
return image
end getOverlayImage
to readImageFromFile(posixFile)
set image to missing value
set imageData to current application's NSData's dataWithContentsOfFile:posixFile
if imageData is not missing value then set image to current application's NSImage's alloc's initWithData:imageData
return image
end readImageFromFile
to writeImageToFile(image, posixPath)
set imageData to image's TIFFRepresentation()
set imageRep to current application's NSBitmapImageRep's imageRepWithData:imageData
set imageType to imageRep's representationUsingType:(current application's NSBitmapImageFileTypePNG) |properties|:(missing value)
imageType's writeToFile:posixPath atomically:true
end writeImageToFile
to output(image)
if setIcon then -- set the icon
set outputPath to POSIX path of (choose folder with prompt "Choose a folder to set its icon:")
current application's NSWorkspace's sharedWorkspace's setIcon:image forFile:outputPath options:0
else -- save to a file
set outputPath to POSIX path of (((path to desktop folder) as text) & "Composite Folder Icon Image.png") -- or whatever
writeImageToFile(image, outputPath)
end if
end output