Set icon to dmg file not working with icns and png - dmg

I am creating a dmg file and getting following error while using the icns and png files..
Here is the command:
DeRez -only icns resources/test.icns > icns.rsrc
Error:
/Applications/Xcode.app/Contents/Developer/usr/bin/DeRez - SysError
-39 during open of resource file "resources/test.icns"
Mac OS version: macOS mojave 10.14.2
Please suggest.

Encountered this just now as well and noticed this question has gone unanswered, even though it's fairly simple.
Apparently error -39 means end of file, I'm assuming this means it wasn't able to find a valid portion of expected data. I'm guessing you (like myself) used sips -i someicon.icns to set the file's icon to itself? You should've gotten an error --addIcon is no longer supported which to me means that it didn't actually set the icon. So a subsequent DeRez call to get a .rsrc out of it will fail.
I didn't want to install any extra stuff but luckily I found another answer on here that seems to use only standard Xcode and/or macOS tools. In my case I was trying to set an AppleScript-exported .app icon, but the actual conversion part should be the same regardless.
So, all the steps to go from .png to an actual icon for an .app file:
cd /some/application/dir/some.app/Contents/Resources
cp /some/assets/dir/myicon.png ./
# Convert png to icns
# Keep in mind that sips can allegedly only handle 256x256, 512x512 and 1024x1024 PNGs for this
# Otherwise you need to do something like the following first:
# sips -z 256 256 myicon.png --out myicon_resized.png
# Then check if it came out good and run:
# mv -f myicon_resized.png myicon.png
# Now let's actually convert it and remove the png as it's no longer needed
sips -s format icns myicon.png --out myicon.icns
rm -fv myicon.png
# Apparently you can also specify commands of some sort in .rsrc files (this is the part I needed from the other SO answer)
# This is used in place of DeRez
echo "read 'icns' (-16455) \"myicon.icns\";" > myicon.rsrc
# Now just use Rez to append it to the special icon file in the root of the .app dir
Rez -append myicon.rsrc -o $'../../Icon\r'
# Write the metadata indicating we want to use the Icon\r file for the app's icon
# I could just use ../../ for the path but I like to be explicit
SetFile -a C ../../../some.app
# Also hide said file from Finder views
SetFile -a V $'../../Icon\r'
I haven't tried setting custom icons for a .dmg file, but I guess you already know how to "apply" the .rsrc to it anyways. =]

Related

Piping an image retrieved using curl to sips to change format without saving intermediate file

I have url links to image files I want to retrieve from the internet.
I can download the files using curl without issue using:
curl "https://...web address..." > myfileName;
The image files are of various types, some .bmp some .jpg etc. I have been using sip in Terminal on Mac osx to convert each to .png files using:
sips -s format png downloadFileName --out newFileName.png
This works well on files I've saved as downloadedFileName regardless of the starting file type.
As I have many files to process I wanted to pipe the output of the curl download directly into sips, without saving an intermediate file.
I tried the following (which combines my two working steps without the intermediate file name):
curl "https://...web address..." | sips -s format png --out fileName.png
And get a no file error: Error 4: no file was specified.
I've searched the sip man pages but cannot find a reference for piped input and have been unable to find a useful answer searching SO or google.
Is there a way to process an image downloaded using curl directly in sips without first saving the file?
I do not necessarily need the solution to use a pipe, or even be on one line. I have a script that will cycle through a few thousand urls and simply want to avoid saving lots of files that will be deleted a line later.
I should add, I do not necessarily need to use sips either. However, any solution must be able to handle image files of unknown type (which sips does admirably) as no file extension is present on the files.
Thanks
I don't have sips installed but its
manpage indicates that it cannot read
from stdin. However, if you use Bash or ZSH (MacOS default now) you
can use process substitution, in this example I use convert which is
a part of ImageMagick and can convert different image types too:
$ convert <(curl -s https://i.kym-cdn.com/entries/icons/mobile/000/018/012/this_is_fine.jpg) this_is_fine.png
$ file this_is_fine.png
this_is_fine.png: PNG image data, 800 x 450, 8-bit/color RGB, non-interlaced
After doing that this_is_fine.png will be the only file in the
directory with no temporary files
Apparently sips only reads regular files which makes it impossible to use /dev/stdin or named pipes.
However, it is possible using the mature and feature-rich convert command:
$ curl -sL https://picsum.photos/200.jpg | convert - newFilename.png
$ file newFilename.png
newFilename.png: PNG image data, 200 x 200, 8-bit/color RGB, non-interlaced
(First install ImageMagick via brewinstall imagemagick or sudoportinstall ImageMagick.)
ImageMagick permits image data to be read and written from the standard streams STDIN (standard in) and STDOUT (standard out), respectively, using a pseudo-filename of -.
source, section STDIN, STDOUT, and file descriptors

Convert a PDF to Images using sips

I want to convert a pdf with several pages to single image files using sips. I know there are several other (probably better) solutions to do this but sips is installed on every mac and don't need a licence.
What I tried:
sips -s format png myPDF.pdf --out myIMG.png
That gives me an image of the first site from the pdf.
Now my Question: Is there a possibility to get images for each page of the pdf?
Thanks for your advise!
I have no idea whether you are supposed to do this sort of thing this way, but the Automator on macOS has an action called Split PDF which you could use to split a PDF into separate pages and then use sips on each one...
To start Automator, press ⌘space and start typing Automator till it guesses correctly and hit ↩. This is called a Spotlight Search apparently and is the quickest way to find anything on a Mac but no-one tells you that!
Then create a new Application, and select PDFs on the left (highlighted in red), then Split PDF (also in red) and drag that into the "work-area" on the right.
I saved that then as splitter.
Then I started Terminal - same Spotlight Search method as starting Automator above, but start typing Terminal instead.
Now go to where you saved splitter and you'll see splitter.app:
ls -ld splitter*
drwxr-xr-x# 3 mark staff 96 27 Nov 12:09 splitter.app
Now I want to split a 10-page document called "a.pdf", so I ran:
echo "a.pdf" | automator -i - ./splitter.app
Sample Output
2018-11-27 12:15:21.200 automator[24004:3655998] Cache location entry for /Applications/Photos.app in cache file at /Users/mark/Library/Caches/com.apple.automator.actionCache-bundleLocations.plist is not valid: (null)
(
"/Users/mark/Desktop/a-page1.pdf",
"/Users/mark/Desktop/a-page2.pdf",
"/Users/mark/Desktop/a-page3.pdf",
"/Users/mark/Desktop/a-page4.pdf",
"/Users/mark/Desktop/a-page5.pdf",
"/Users/mark/Desktop/a-page6.pdf",
"/Users/mark/Desktop/a-page7.pdf",
"/Users/mark/Desktop/a-page8.pdf",
"/Users/mark/Desktop/a-page9.pdf",
"/Users/mark/Desktop/a-page10.pdf"
)
And it spits out 10 separate 1-page PDF documents on my desktop named per the output.
I have no idea what the warning about "Photos App" cache file means, so if anyone knows, maybe they would tell me what it means and how to get rid of it.
Also, I presume that Automator is somehow calling the action from /System/Library/Automator/Split PDF.action:
file "/System/Library/Automator/Split PDF.action/Contents/MacOS/Split PDF"
/System/Library/Automator/Split PDF.action/Contents/MacOS/Split PDF: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [i386:Mach-O bundle i386]
/System/Library/Automator/Split PDF.action/Contents/MacOS/Split PDF (for architecture x86_64): Mach-O 64-bit bundle x86_64
/System/Library/Automator/Split PDF.action/Contents/MacOS/Split PDF (for architecture i386): Mach-O bundle i386
But, I have no idea how I can execute/call that from Terminal, without needing to start/write any Automator stuff. So, if anyone, #vadian maybe, knows, I would love to know that too! It appears to be a bundle, but if I run mdls on it, there is no bundle identifier listed, so I cannot run it with:
open -b <BUNDLE-IDENTIFIER>
This will do it and let you set your resolution for the rasterization:
sips -s format png in.pdf -z 1024 1024 --out out.png
for all pdf files in directory and subdirectories:
find . -name "*.pdf" -exec sips -s format png {} -z 1024 1024 --out {}.png \;
the -exec part of this executes the rest as a command for each matching file until the \; terminator, while replacing {} with each file it finds. Super handy!

How to convert images from TIFF to JPG preserving the comments and tags

I am using preview (that comes with OS X El Capitan) feature to convert a file form TIFF format into JPG for example. I expected the export process will include the original comments, but it doesn't happen (it applies also for the tag fields).
The generated JPG file has no comment
The compression and change image format work, but the META INFO such as comment or tags are not exported.
Any suggestion or workaround about how to include that information. I need to convert about 500 images so manually copy/paste doesn't work for me.
Updated Answer
In the light of your comments, I think the best way forward is to try and identify how/where the comments are stored for each platform (Windows vs macOS) and then to decide which method you want to use going forward.
macOS Finder/Spotlight comments will not be legible on Windows, so if you want Windows compatibility, you need to standardise on JPEG or EXIF comments.
I recommend using exiftool which you can install with homebrew, using:
brew install exiftool
Then I suggest you try extracting the comments from your files to see how/where they are stored:
exiftool -a image.jpg
will show you all tags in image.jpg. Your comments may be under:
comment - which is the JPEG comment, or
EXIF:UserComment - which is the EXIF comment
If you find your comments in the JPEG or the EXIF section, you can extract just the comments with:
exiftool -comment image.jpg # extract JPEG comment
exiftool -EXIF:UserComment image.jpg # extract EXIF UserComment
Add the option -s3 to suppress the field-names in the above to save having to parse them out.
Likewise, you can set the comments with:
exiftool -comment="FUNKY JPEG COMMENT" image.jpg # set JPEG comment
exiftool -EXIF:UserComment="FUNKY EXIF USER COMMENT" image.jpg # set EXIF UserComment
You can also extract the EXIF user comments to a CSV with:
exiftool -EXIF:UserComment -csv *.jpg
SourceFile,UserComment
a.jpg,FUNKY EXIF:UserComment
b.jpg,b FUNKY EXIF:UserComment
You can also apply comments from a CSV.
You should also be able to extract macOS/Spotlight/Finder comments using the script in my main answer:
$HOME/macOSGetFinderComment "/Users/someone/soneFile.tif"
Original Answer
I would suggest you try the following using ImageMagick.
First, use the Finder, or any other tool you are familiar with, to make a copy of your photos including the entire directory structure to some new place where we cannot damage your existing photos. So, let's say you copy (NOT move) the entire tree of TIFs to a subdirectory called "NEW" inside your HOME directory.
Then start the Terminal and change directory to "NEW":
cd NEW
Easy Method
If all the TIFs are in a single directory or two, just use mogrify:
mogrify -format jpg *.tif
Harder Method
If the TIF files are in multiple directories, you will need to work a bit harder. Inside Terminal copy and paste this:
find NEW -name \*.tif -exec sh -c 'new="${1%.tif}.jpg"; convert "{}" "$new"' _ {} \;
That starts looking in the "NEW" directory for files named "*.tif". When it finds one, it starts a new shell (sh) passing it the filename of the TIF. It then works out the new filename by replacing a trailing "tif" with "jpg" and invokes ImageMagick convert to do the conversion.
As regards the Finder/Spotlight comments, here is a little script to get the Finder comment of a file:
#!/bin/bash
# macOSGetFinderComment
# Pass an absolute path to the file!
file=$1
osascript<<EOF
tell application "Finder" to get comment of item POSIX file "$file"
EOF
And here is one to set the Finder/Spotlight comment:
#!/bin/bash
# macOSSetFinderComment
# Pass an absolute path to the file!
file=$1
comm=$2
osascript<<EOF
tell application "Finder" to set comment of item POSIX file "$file" to "$comm"
EOF
So, I would save those 2 scripts in your HOME directory and then make them executable with:
cd
chmod +x macOS*FinderComment
Then save this file in your HOME directory under $HOME/CopyComments:
#!/bin/bash
shopt -s nullglob
for f in $(pwd)/*.tif; do
comment=$($HOME/macOSGetFinderComment "$f")
new="${f%.tif}.jpg"
echo Setting comment of $new to $comment
$HOME/macOSSetFinderComment "$new" "$comment"
done
and make it executable with:
chmod +x $HOME/CopyComments
and run it with:
cd NEW
$HOME/CopyComments
I have posted this problem also in Apple Community, here is the solution proposed by VikingOSX. It is a big piece of code, so better download it from here or directly from the Apple Community Link mentioned. Here is a description about the solution as described in the original post:
Prompts for a source folder, and a destination folder.
Duplicates folder hierarchy from source to destination folder.
Selects all TIFF images in the folder hierarchy and converts them to JPEG.
For sub-folders and their files, transfers the original Finder comments, color tags and tag name(s) to the destination hierarchy.
The compression level for the JPG file is high, it can be modified for: medium or low in the line: save this_img as JPEG in outfile_name with compression level medium with icon
Limitation: Source folder can only contain one-level of sub-folders. Ignoring this will result in unplanned results.
Additional Comments
Uses a with timeout clause to allow for large number of files. AppleScript does not yet support Finder tag names, so this script uses AppleScript/Objective-C to get and set those tag name(s). Due to this extension, the script now requires AppleScript 2.4 and must be run on OS 10.10 or later.
Due to the AppleScript/Objective-C code, the script cannot be run interactively as a script/script bundle without using the control+command+R keyboard shortcut. A test is made when the script starts, and will warn appropriately. It is best to save the script as an application to avoid this keyboard shortcut altogether.
Usage
Save the script and then copy and paste the file contains into the Script Editor (you can find the application in the folder: Utilities under the name: Script Editor), compile and save the file with the format: Application, then double click on it to run the script application.
I have tested the script under with Mac Air 2010, with OS El Capitan, for a folder with 884 TIFF files with 2.25GB size and it takes about 18 minutes to convert them into JPG files with medium compression level. The generated files will contain the tags and comments from the original equivalent TIFF file.
Disclaimer
Comment and tags generated in one platform for example Windows or mac OS are not visualized in the other platform. Tags created in Windows are treated in mac OS as keywords (Comand+i for visualizing them), but comments generated in Windows are not visualized in mac OS. This is general incompatibility problem that apply for photos in any format (for example TIFF or JPG).
EDIT (updated solution for solving cross-platform problem with comments)
Taking the idea from #MarkSetchell, I adapted the original script to at least solve the cross-platform problem from macOS to Windows, i.e. a comment from macOS can be seen in Windows platform. The idea is to use EXIF metadata. Then the Applescript will invoke the shell script for invoking the exiftool:
set uxFilepath to POSIX path of NewIMG
do shell script "/usr/local/bin/exiftool -overwrite_original -EXIF:UserComment=\"" & cmtstr & "\" " & uxFilepath
Windows processes the UserComment metadata from EXIF as a regular file comment. Now same comment on the TIF file will be on the JPG and also because such comments were copied (copy-paste) into an EXIF metadata the same information will be visualized under Windows. The same idea can be used for other file properties, in case Windows/Mac read it.
The EXIF metadata in macOS can be visualized from command line as suggest #MarkSetchell, but also from Finder: Command+o (to launch preview app), then Command+i (to launch the inspector). Then click on tap: "More Info", then the tab EXIF.
For the opposite process will require an script that does the opposite, i.e., copy EXIF comment using exiftool, into macOS comment. I have verified that in such case the Windows comment will appear under the label: XPComment. The script uses: UserComment, but it works using XPComment as label in both directions.

Changing icon of package created by package maker

I have created package (.pkg) file using packagemaker ver 3.0.4. Is it possible to provide custom icon to the .pkg file. Can some one help me how this can be done ?
Thanks in advance.
The same way you set any other file's, folder's, or package's custom icon.
Setting an icon for an mpkg, works fine
# create a file that actually going to set the icon file
touch <package_name>.mpkg/Icon$'\r'
# --- copy the customIcon.icns file to the <package_name>.mpkg before doing the sips, if its needed you
# can take a copy of the file before doing the sips command, doing on a copied file will do good
sips -i <package_name>.mpkg/customIcon.icns
DeRez -only icns <package_name>.mpkg/customIcon.icns > tmpIcon.rsrc
Rez -append tmpIcon.rsrc -o $'<package_name>.mpkg/Icon\r'
SetFile -a C <package_name>.mpkg
# removing the tmp file
rm tmpIcon.rsrc
# remove the .icns from mpkg
rm <package_name>.mpkg/customIcon.icns
# if you want you can hide the Icon$'\r' file inside the .mpkg file, file that presently sets the icon
SetFile -a V <package_name>.mpkg/Icon$'\r'
Hope this helps.

Creating a .DMG

I want to create a dmg file for my Mac project. Can someone please tell me how to do this? This being my first Mac project, I do not have any idea how to proceed. I also want to give the user an option of running the app on start-up. How do I do this?
Thanks.
P.S. I also want to add a custom license agreement.
To do this manually:
Method 1:
Make a folder with the files your DMG will contain.
Open Disk Utility (It's in /Applications/Utilities/)
Go to File > New > New Image from Folder (Cmd + Shift + N)
Choose the folder containing you files
Make sure "Compressed" is checked, then set where you want to save the created DMG
Method 2:
To do things like setting a background image can be a bit convoluted (You basically add the background image to the DMG, set the windows properties to use that image, using the command line you move the background image from background.png to .background.png to make it hidden)
I would recommend iDMG, which makes things a bit less tedious.
You can also script the creation of DMGs using the command hdiutil. Something along the lines of
hdiutil create -srcfolder mydirtodmg mydmg.dmg
As for the custom license agreement, you should look into the tool included with the Developer Tools "PackageMaker" - it's pretty self-explanatory. It's in /Developers/Application/Utilities/
If you need to add a custom EULA to your disk image, this page describes how to do so using command-line tools. The gist of it is to use the template software licensing agreement resource provided in Apple's slas_for_udifs_1.0.dmg, modify the resource with your EULA text and inject the resource back into your disk image file. (I include brief instructions below in case the above link becomes unavailable, and to update the search term it provides in step 1.)
Using your Apple Developer account go to the Downloads page and search for Software Licensing for UDIF
Download and mount the disk image
In Terminal:
cd /Volumes/SLAs_for_UDIFs_1.0
DeRez SLAResources > /tmp/sla.r
Edit /tmp/sla.r in a text editor, updating the content of the data 'TEXT' (5000, "English SLA") resource to contain your new license text.
Unflatten the disk image file that contains your installer:
hdiutil unflatten installer_image.dmg
Add the edited license resources to the image:
Rez -a /tmp/sla.r -o installer_image.dmg
why don't you just run a script from your xcode project. try something like this:
# be sure to check the man page for hdiutil
# it is very powerful and has tons of options...
hdiutil create -megabytes 54 -fs HFS+ -volname awesome_app_install myAwesomeApplication.dmg
hdiutil mount myAwesomeApplication.dmg
cp -r /build/Release/AwesomeApplication.app /Volumes/awesome_app_install/
then save your script as something like 'makeDMG.sh' and in your target,
select add->new build phase->run script build phase
and drag your script into this build phase.
once you've done all that, then when you build your project the script will create the disk image and copy your release build into it...
of course you should spice your script to flavor... these three lines are just the raw meat
ps: your custom EULA should get built into your packagemaker project (which you can also script very nicely)
I made a little bash script to automate a disc image creation.
It creates a temporary directory to store all needed files then export it in a new DMG file. Temporary directory is then deleted.
You can automatically launch this script at the end of your build process.
#!/bin/bash
# Create .dmg file for macOS
# Adapt these variables to your needs
APP_VERS="1.0"
DMG_NAME="MyApp_v${APP_VERS}_macos"
OUTPUT_DMG_DIR="path_to_output_dmg_file"
APP_FILE="path_to_my_app/MyApp.app"
OTHER_FILES_TO_INCLUDE="path_to_other_files"
# The directory of the script
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# The temp directory used, within $DIR
WORK_DIR=`mktemp -d "${DIR}/tmp"`
# Check if tmp dir was created
if [[ ! "${WORK_DIR}" || ! -d "${WORK_DIR}" ]]; then
echo "Could not create temp dir"
exit 1
fi
# Function to deletes the temp directory
function cleanup {
rm -rf "${WORK_DIR}"
#echo "Deleted temp working directory ${WORK_DIR}"
}
# Register the cleanup function to be called on the EXIT signal
trap cleanup EXIT
# Copy application on temp dir
cp -R "${APP_FILE}" "${WORK_DIR}"
# Copy other files without hidden files
rsync -a --exclude=".*" "${OTHER_FILES_TO_INCLUDE}" "${WORK_DIR}"
# Create .dmg
hdiutil create -volname "${DMG_NAME}" -srcfolder "${WORK_DIR}" -ov -format UDZO "${OUTPUT_DMG_DIR}/${DMG_NAME}.dmg"

Resources