How to set icon for bundle which is not an app? I tried using CFBundleIconFile, but it doesn't work (though if I just change bundle extension to .app, icon is changed to desired one). Is there another key, or the only way is to set icon for directory? If so, is there already some script to do this from command line (Xcode run script)?
If you need to do it from CLI... It's a bit more involved...
First, you need to add a CFBundleIconFile string to your bundle's
YourThing.bundle/Contents/Info.plist
Here's where the developer gets to
specify a custom icon for the bundle.
This key contains the name of a file
in the bundle's Resources folder that
holds the icons. TextEdit keeps its
icon in a file called Edit.icns file,
but there's no rule about what the
name of the file must be.
That said, you either need an ICNS file, or can follow these instructions from this Utility (which includes its source code) that generates ICNS's from image files via the command line..
$ ./makeicns
Usage: makeicns [k1=v1] [k2=v2] ...
Keys and values include:
512: Name of input image for 512x512 variant of icon
256: Name of input image for 256x256 variant of icon
128: Name of input image for 128x128 variant of icon
32: Name of input image for 32x32 variant of icon
16: Name of input image for 16x16 variant of icon
in: Name of input image for all variants not having an explicit name
out: Name of output file, defaults to first nonempty input name,
but with icns extension
Examples:
makeicns -512 image.png -32 image.png
Creates image.icns with only a 512x512 and a 32x32 variant.
makeicns -in myfile.jpg -32 otherfile.png -out outfile.icns
Creates outfile.icns with sizes 512,
256, 128, and 16 containing data
from myfile.jpg and with size 32 containing data from otherfile.png.
Answer from similar (duplicate) question:
[[NSWorkspace sharedWorkspace]
setIcon:(NSImage *)image
forFile:(NSString *)bundlePath
options:0];
Related
I am converting a .ttf/.otf font file reader in Lua 5.2 from Windows to MacOS and also want to add support for .suit font files which include ttf fonts.
Plain .ttf/.otf files now work fine, but already the reading of a .suit file doesn't work.
Any ideas on how to read the bytes of the .suit font on MacOS?
Does it have to do with a file name alias?
local input = assert(io.open("/Library/Fonts/Tahoma.ttf", "rb"))
local data=input:read("*all")
print(string.byte(data,1)) --prints the correct value 0
io.close(input)
local input = assert(io.open("/Library/Fonts/Maestro.suit", "rb"))
local data=input:read("*all")
print(string.byte(data,1)) --prints nothing
io.close(input)
The upper part (Tahoma) prints the correct first byte value 0, while the bottom part prints nothing, although I would have expected the value 0.
When I use string.len(data), it shows the correct value for Tahoma, but 0 for Maestro, although it should be something like 46k.
See https://apple.stackexchange.com/questions/8455 .suit is not a folder, but it can be addressed like a folder. To open the font part in the .suit file use:
local file=io.open("/Library/Fonts/Maestro.suit/..namedfork/rsrc","rb")
Let's say I have many jpg files which all have this format: X-Y.jpg while X and Y are numbers from 0 to 99 and also define the location of themselves in the final image.
Now I've tried this command to create one image out of those many tiles.
montage.exe -tile 99x99 #D:\img\list.txt D:\output\out.jpg
But it expands my image file list not correctly.
montage.exe: unable to open image '#D:D:\input\0-59.jpg': Invalid argument # error/blob.c/OpenBlob/3489.
Here is a reference for the imagemagick manual, where it says for large numbers of files you can read a list of input files from a specific file by "#in.txt": http://www.imagemagick.org/script/command-line-processing.php#input
Put the filenames in the list.txt without any prepending directory.
Put the list.txt file into the folder where all tiles are located
Open cmd and change to the directory with all the tiles and the list.txt
montage -tile 63x63 #list.txt out.jpg
Thanks to the user snibgo from https://www.imagemagick.org/discourse-server who helped me with a hint.
This is a pseudo question to share my own trick and script below.
The point is to be able to display image pixel for pixel on Retina displays. This is mainly useful for high resolution image and/or for developers working on HDPI version of images.
The solution works well only if the display setting is set to 2:1 ratio in the OS X preferences. Beware, late 2016 MacBook Pro default setting is not set to 2:1 by default. You should set it on the medium setting to get it right.
Finder : the simple trick is to give a name ending with #2x (before the extension): my_image#2x.jpg . Then when using Quick Look feature the image is pixel-wise. As this naming scheme is recommended for retina images, both normal and HDPI images display at same size, as expected, the retina being sharper.
Preview : In preview, the DPI resolution of an image is interpreted as normal if it is set to 72dpi. By setting it to 144, you get the right display ratio. One can achieve the same effect at 72dpi by changing the display scale to 50%, but the scale setting does not stick to the image file while the DPI setting does. Change it through the Tools->Size menu item.
Here below is a small applescript to automate 144dpi setting from the Finder.
tell application "Finder"
repeat with item_cour in selection as list
if word 1 of (the kind of item_cour as text) is "Image" then
set path_cour to POSIX path of (item_cour as text)
do shell script "p_cour='" & path_cour & "';
tags=$(xattr -px com.apple.metadata:_kMDItemUserTags \"$p_cour\");
f_info=$(xattr -px com.apple.FinderInfo \"$p_cour\");
sips -s dpiHeight 144 -s dpiWidth 144 \"$p_cour\";
xattr -wx com.apple.FinderInfo '$f_info' \"$p_cour\";
xattr -wx com.apple.metadata:_kMDItemUserTags \"$tags\" \"$p_cour\" "
-- do shell script "convert \"" & path_cour & "\" -set units PixelsPerInch -density 144 \"" & path_cour & "\""
end if
end repeat
end tell
Since the sips command does not preserve tags, the script includes 4 lines to get and set them back to the file after it has been modified, using the xattr command.
To install the script: open the script editor, create a new document, paste the code and save it into the ~/Library/Scripts/Finder folder.
Be sure to check the Show the Script Menu option in Script editor preference.
To use the script: select image file(s) in Finder and activate the script from the menu.
Is it possible to change the icon of a Mac folder using a set of Ruby commands? I believe that OSX requires a .icon file to be present within the modified folder, perhaps there is a specific way of converting a jpg or png to the .icon criteria?
-- Edit (Working solution. Requires ImageMagick and OSXUtils)
* note, for my application I intended to set folder icons. It is entirely possible this could work for files as well.
def set_icon image, folder
# Convert to absolute paths and setup
image = File.expand_path image
folder = File.expand_path folder
dim = 512
thumb = folder + '/'+ 'thumb.png' # PNG supports transparency
icon = folder + '/'+ 'icon.icns'
# Convert original to thumbnail
system "convert '#{ image }' -quiet -thumbnail '#{dim}x#{dim}>' \
-background none -gravity center -extent #{dim}x#{dim} '#{ thumb }'"
# Set icon format. Causes 'libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area'
system "sips -s format icns '#{ thumb }' --out '#{ icon }'"
# Set the icon
system "seticon -d '#{ icon }' '#{ folder }'"
# Cleanup
FileUtils.rm thumb
FileUtils.rm icon
end
It's been years since I played with them, but .icon files' format were documented by Apple's documentation and Wikepedia.
If I remember right, the name has a trailing "\r" to make it harder to type, but that's easily handled from code.
You should be able to use the normal File.rename method to move an .icon file into a folder, and the Finder should do the right thing.
Looking at your code, I'd do some things differently:
require 'fileutils'
def set_icon image, folder
# Convert to absolute paths and setup
image = File.expand_path image
folder = File.expand_path folder
temp = File.join(folder, 'temp2' + File.extname(image))
# Copy image
FileUtils.cp(image, temp)
# Take an image and make the image its own icon
system "sips -Z 512 -i #{ temp }"
# Extract the icon to its own resource file
system "DeRez -only icns #{ temp } > tmpicns.rsrc"
# Append a resource to the folder you want to icon-ize
system "Rez tmpicns.rsrc -o $'#{ folder }/Icon\r'"
# Use the resource to set the icon.
system "SetFile -a C #{ folder }"
end
Rather than rely on sprintf or % ("format") to build the strings, instead use simple interpolation. sprintf strings are great when you need to force column widths and coerce values into a different representation, but they're overkill when you're inserting a single value that isn't formatted.
sips has this option, which looks promising, but it's not documented well in the man page:
-i
--addIcon
Add a Finder icon to image file.
Also, Stack Overflow's sibling site "Ask Different" has "Why setting image as its own icon with sips result a blurred icon? Are there any alternatives?", "How do I set an icon for a directory via the CLI? and "Changing a file or folder icon using the Terminal" which look useful.
I have an application that I've bundled into a Mac OS X app bundle. Everything is working fine, but I want to change its icon from the default. How do I set its icon? Thanks.
in your info.plist add
<key>CFBundleIconFile</key>
<string>iconfile</string>
with icon file iconfile.icns in your Resources directory
I made a small script that takes a big image and resizes it to all expected icon sizes for Mac OS, including the double ones for retina displays. It takes the original png file, which I expect to be as big as the maximum size, if not bigger, to make sure they are rendered at maximum quality.
It resizes and copies them to a icon set, and uses the Mac OS's 'iconutil' tool to join them into a .icns file.
For this script to run, you need your original icon file to be a png, and you have your bundle in more or less working order. You only need to touch the first three lines.
export PROJECT=Myproject
export ICONDIR=$PROJECT.app/Contents/Resources/$PROJECT.iconset
export ORIGICON=Mybigfile.png
mkdir $ICONDIR
# Normal screen icons
for SIZE in 16 32 64 128 256 512; do
sips -z $SIZE $SIZE $ORIGICON --out $ICONDIR/icon_${SIZE}x${SIZE}.png ;
done
# Retina display icons
for SIZE in 32 64 256 512; do
sips -z $SIZE $SIZE $ORIGICON --out $ICONDIR/icon_$(expr $SIZE / 2)x$(expr $SIZE / 2)x2.png ;
done
# Make a multi-resolution Icon
iconutil -c icns -o $PROJECT.app/Contents/Resources/$PROJECT.icns $ICONDIR
rm -rf $ICONDIR #it is useless now
If you came here because you have a single app and want to change the image on your computer only (not sure how it works for sharing), there are much easier ways. In particular, here are two options I have used:
If you want to copy an existing icon:
Select the source item and press Cmd-I (Apple-I)
Select the item you want to change and press Cmd-I (Apple-I)
Drag the icon from the source to the top left icon of the one you want to change (the example image shows the target icon: it is the 'folder' icon to the left of the words "bird_id 2"):
Create a .icns file from any image. If you use MacPorts, I recommend instead using the port makeicns - see below for more info. You can alternatively do this using an app such as http://www.img2icnsapp.com/ as recommended at https://discussions.apple.com/thread/2773825.
makeicns v1.4.10 (284bd686824f)
Usage: makeicns [k1=v1] [k2=v2] ...
Keys and values include:
512: Name of input image for 512x512 variant of icon
256: Name of input image for 256x256 variant of icon
128: Name of input image for 128x128 variant of icon
32: Name of input image for 32x32 variant of icon
16: Name of input image for 16x16 variant of icon
in: Name of input image for all variants not having an explicit name
out: Name of output file, defaults to first nonempty input name,
but with icns extension
align: [center, left, right, top, bottom] {First letter suffices!}
Examples:
makeicns -512 image.png -32 image.png
Creates image.icns with only a 512x512 and a 32x32 variant.
makeicns -in myfile.jpg -32 otherfile.png -out outfile.icns
Creates outfile.icns with sizes 512, 256, 128, and 16 containing data
from myfile.jpg and with size 32 containing data from otherfile.png.