use framework "Foundation"
use framework "AppKit"
use scripting additions
set fromPosix to "/Users/ionah/Desktop/111/"
set toPosix to "/Users/ionah/Desktop/222/"
set imageData to (current application's NSWorkspace's sharedWorkspace's iconForFile:fromPosix)
(current application's NSWorkspace's sharedWorkspace()'s setIcon:imageData forFile:toPosix options:0)
(current application's NSWorkspace's sharedWorkspace's noteFileSystemChanged:toPosix)
When copying a custom icon with the setIcon method, the result is not what is expected:
The pasted icon is always different from the original in terms of colors & shadow.
In late system 9, I had a script that was able to read an write the “icns” resource (number -16455 or -16496).
Is it possible to do this or something similar with AppleScriptObjC?
I can get the icon data from the pasteboard but can’t find how to read/write the resource from/to a file or folder.
use framework "Foundation"
use framework "AppKit"
set POSIXPath to "/Users/ionah/Desktop/333.icns"
set thePasteboard to current application's NSPasteboard's generalPasteboard()
set theData to thePasteboard's dataForType:"com.apple.icns"
theData's writeToFile:POSIXPath atomically:true
Icons are no longer stored as resources – they’re files in the bundle, with a suitable entry in the app’s Info.plist file.
I suspect the problem you’re seeing is because iconForFile: returns a 32 pixel x 32 pixel image, and setIcon:forFile:options: sets an image 512 pixels x 512 pixels.
You will probably do better just to use an image file.
use framework "Foundation"
use framework "AppKit"
use scripting additions
set fromPosix to "/Users/ionah/Desktop/111/Some pic.tif" -- whatever
set toPosix to "/Users/ionah/Desktop/222/"
set theImage to (current application's NSImage's alloc()'s initWithContentsOfFile:fromPosix)
(current application's NSWorkspace's sharedWorkspace()'s setIcon:theImage forFile:toPosix options:0)
The problem is not with initWithContentsOfFile: but with iconForFile: when copying the custom icon of a folder.
I tried to avoid this issue by using the pasteboard content.
It ends with what is described above.
The workaround, for me, is to go back to the old shell command invoking osxutils by Sveinbjorn Thordarson.
if sourceFile ends with ".icns" then
(current application's NSWorkspace's sharedWorkspace()'s setIcon:imageData forFile:destPath options:0)
(current application's NSWorkspace's sharedWorkspace's noteFileSystemChanged:destPath)
else
set theShell to "/usr/local/bin/seticon " & quoted form of sourcePath & space & quoted form of destPath
do shell script theShell
end if
I’m using @ShaneStanley’s script to copy a custom icon (saved as a PNG file) to a file’s icon.
here’s the script I ran/tested:
use framework "Foundation"
use framework "AppKit"
use scripting additions
set fromPosix to "/Users/Shared/Dropbox/SW/DEV/Images/Evernote-icon-512x512.png" -- whatever
set toPosix to "/Users/Shared/Dropbox/SW/DEV/Images/TEST for Icon Set.EN.Note.inetloc"
set theImage to (current application's NSImage's alloc()'s initWithContentsOfFile:fromPosix)
(current application's NSWorkspace's sharedWorkspace()'s setIcon:theImage forFile:toPosix options:0)
I created the PNG file by:
Copy Icon from Evernote app
Save to file using SnagIT
Resize to 512x512 (it was smaller)
Save as PNG file using SnagIT
I also tried using a TIFF file, but did not see any difference, except that the TIFF file was >> than the PNG file (of course). So I don’t see any need to use TIFF.
It’s not about using initWithContentsOfFile which gets the content of an image file (png, tiff, jpg, icns…).
In this case, the icon placed on a file is perfect.
The problem is with iconForFile that takes the icon resource as you could do by using the file info window in Finder (commad+i).
Try the first script I posted:
use framework "Foundation"
use framework "AppKit"
use scripting additions
set fromPosix to "/Users/ionah/Desktop/111/"
set toPosix to "/Users/ionah/Desktop/222/"
set imageData to (current application's NSWorkspace's sharedWorkspace's iconForFile:fromPosix)
(current application's NSWorkspace's sharedWorkspace()'s setIcon:imageData forFile:toPosix options:0)
(current application's NSWorkspace's sharedWorkspace's noteFileSystemChanged:toPosix)
This is the kind of result I get with this script:
You said iconForFile uses a 32x32 pixels icon rendering.
The strange thing is that if the icon size is under 128 I get the result shown in the above screen capture.
But if icon size is set to a value > 128, I get this:
set theURL to listURL's firstObject()
if (theURL's pathExtension()'s isEqualToString:"icns") as boolean then
set theImage to (current application's NSImage's alloc()'s initWithContentsOfURL:theURL)
else
set {theResult, theImage, theError} to theURL's getResourceValue:(reference) forKey:(current application's NSURLCustomIconKey) |error|:(reference)
end if
set theWorkspace to (current application's NSWorkspace's sharedWorkspace())
set theResult to (theWorkspace's setIcon:theImage forFile:(theURL's |path|()) options:0)
Thanks for the tip, but I can’t test this method: NSURLCustomIconKey is only compatible with 10.12 and I’m stuck with El Capitan.
But I suspect the result will be the same as with the icns ressource extracted from the pasteboard: a clean but fade out icon. (see post 4)
I tried another approach, but it ends the same:
set theIcon to (current application's NSWorkspace's sharedWorkspace()'s iconForFile:sourcePath)
set theData to current application's NSImage's alloc's initWithData:((theIcon's representations()'s lastObject())'s TIFFRepresentation())
set theResult to (current application's NSWorkspace's sharedWorkspace()'s setIcon:theData forFile:destPath options:2)
(current application's NSWorkspace's sharedWorkspace's noteFileSystemChanged:destPath)
I’m wondering if the problem could be with the color space from the image data? And if we could get the icon data with the accurate color space by using core image or core graphics?
Nevertheless, the following always returns: {true, missing value, missing value}
set theURL to current application's NSURL's fileURLWithPath:thePath
set {theResult, theImage, theError} to theURL's getResourceValue:(specifier) forKey:(current application's NSURLCustomIconKey) |error|:(specifier)
(Naturally, thePath is a folder with a custom icon)
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"
set picPath to POSIX path of (choose file with prompt "Choose pic file")
set theImage to current application's NSImage's alloc()'s initWithContentsOfFile:picPath
set thePath to POSIX path of (path to desktop)
set thePath to current application's NSString's stringWithString:thePath
set anNSURL to current application's |NSURL|'s fileURLWithPath:thePath
set destURL to anNSURL's URLByAppendingPathComponent:"Test folder"
set fm to current application's NSFileManager's defaultManager()
fm's createDirectoryAtURL:destURL withIntermediateDirectories:true attributes:(missing value) |error|:(missing value)
set ws to current application's NSWorkspace's sharedWorkspace()
ws's setIcon:theImage forFile:(destURL's |path|()) options:0
set theImage to (ws's iconForFile:(destURL's |path|()))
repeat with i from 1 to 10
set newURL to (destURL's URLByAppendingPathComponent:("Folder " & i))
(fm's createDirectoryAtURL:newURL withIntermediateDirectories:true attributes:(missing value) |error|:(missing value))
(ws's setIcon:theImage forFile:(newURL's |path|()) options:0)
set theImage to (ws's iconForFile:(newURL's |path|()))
end repeat
Just as you say. Except… I use an iMac with a retina screen, but I also have a non-retina screen attached to it. And when I drag that same window over to the other screen, it now looks like this:
Totally agree!
But this is half of the problem.
The first issue is with content of file (icns, png, tiff…) like in your posts #16.
The second has something to do with transparency when using iconForFile or NSURLEffectiveIconKey like in my post #15.
But there is something I’m missing: how can a utility like osxutils render the icon perfectly? Is it using something we have no access to, like C+ code?
The author of osxutils has made an opensource project: osxiconutils
Can it be of any help?