Convert a PDF to Images using sips - macos

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!

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

Set icon to dmg file not working with icns and png

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. =]

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.

In Ubuntu, how do I find all photos of the Raw format taken after Jan 1, 2015, and if they total less than 30G, put them on an external drive?

This question has three parts:
How do I find all RAW format photos.
I assume I am going to use the find command. I have used find successfully exactly once:
find . -name creek.jpg
to find creek.jpg in the current folder. How do I search by date? The man page has a list of 'primaries' that allow you to tell find to search by things like date, and it's like reading a foreign language: I can't understand the man page. Also, I assume that find uses the date the photo was uploaded to the system, and not the date in the metadata of the picture itself.
How do I keep a running total of how big these files are?
I have no idea which shell command to use. Should I do it the hacky way and copy the photos into a folder and simply use a shell command to find out how big the folder is? I'm leary of doing that, because I am doing support for a photographer who takes a LOT of raw photos, and I don't want to run her computer out of memory by duplicating raw photos.
I assume putting them on an external drive is as simple as using the cp command.
Thank you for any advice!
You have a bunch of questions to ask and answers to find before you can even get started.
First, you need to know WHERE the files are stored because that is the first parameter for find, e.g.
find $HOME ...
or
find "/mnt/EXTERNAL DRIVE" ...
Second, you need to know the extension of the RAW files the camera creates, it may be .CR2 on a Canon or .TIF or .DNG or .NEF on a Nikon, or .mrw on a Minolta. Then you can get the second parameter for find:
find $HOME -iname "*.NEF"
Good, now you can get a list of the files. But you want to know when they were shot. Unfortunately, Ubuntu isn't going to know that, on its own, though it will know when files were created, so you may find it better to let Ubuntu weed out old files so you don't have to pass them to the next step which will be slower. So, how do we get Ubuntu to only find files newer than 1 Jan 2015 (since files put on disk before then were presumably not shot since January 2015).
Well, one way would be to create a file dated 1 January 2015, and then to tell find to only find newer files. So, let's try that:
# Create file with earliest date we want to find - i.e. 1 Jan 2015
touch -t 201501010000 earliest
Now add an extra parameter to find like this:
find $HOME -iname "*.CR2" -newer earliest
Next, if you want the actual shooting date, you will need to install ImageMagick, or ufraw or dcraw or somesuch to parse your raw files and get the date. Let's say you write a script called CheckIfFileIsNew and make it executable with
chmod +x CheckIfFileIsNew
then you will be able to run that script for all the files:
find $HOME -iname "*.cr2" -exec CheckIfFileIsNew {} \;
Then you need to learn how to grep the date out of a raw file. Then you need to learn how to run stat on a file to find its size. Then you need to learn some awk to total up all the file sizes to see if they exceed 30GB, then you can decide if you want to copy the files to the new place and if you do, you can replace the exec in the original find command with a cp command.
find $HOME -iname "*.cr2" -exec CheckIfFileIsNew {} \; | awk '{total+=$0} END{print $total}'
Your script CXheckIfFileIsNew will look something like:
#!/bin/bash
date=$(identify -verbose "$1" | grep "dng:Timestamp")
# Work out of date is 2015 or 2016
# If date is 2015 or 2016; call `stat` to get the file size, print file size
# Output the size, in bytes, of the filename we were given as parameter
stat -c%s "$1"
Note that the identify command above may be pretty slow if you have a hi-res camera. You could try a command like strings on a couple of your RAW files to see if you can find the date in there that way and it will be miles faster:
strings SomeFile.RAW | grep -i date

How can I select files from list on Mac-OS

I've got a bunch of .cr2 and .jpg files with exact same names. ".cr2" is a file format for digital negative, every .jpg is a converted to 8bit version of cr2-photo. Every photographer with canon camera get this kind of structure: take one picture - get one .cr2 version and one .jpg version. Cr2-s weights a lot, thats why I send jpegs to my clients to filter. After they send back best hundred photos from thousands, I must pick cr2 versions of this photos, one by one. There is gotta be a better way. In windows I find a way to select this files in totalcommander through copy selection to buffer - modifing(replace in text editor every ".jpg" to ".cr2") and then restore selection from buffer. This problem is seemed dumn, but I can't find an answer to mac, it took forever to select this files one by one and all photographers I know doing the same, which is driving me crazy.
Here is a bash script that should do what you want simply by double-clicking it. First you need to edit the first 2 lines to tell it 1) where the CR2 files can be found and 2) where the JPEGs are that the client has accepted.
Initially, I am assuming the CR2 files are somewhere under your login/home directory and that the JPEGs accepted by the client are on your Desktop in a folder called accepted. Edit lines 3 and 4 to reflect the actual situation, then save the following script on your Desktop as GetCR2s.command.
#!/bin/bash
#
# You can edit the next two lines to match your setup
CR2LOCATION="$HOME"
ACCEPTEDLOC="$HOME/Desktop/accepted"
shopt -s nocasematch # Match JPG and jpg and CR2 and cr2 regardless of case
shopt -s nullglob # Don't die if there are no files
# Tell user what is going on...
echo Locating CR2s in $CR2LOCATION, to match accepted files in $ACCEPTEDLOC...
# Go where the JPEGs are, or give up
cd "$ACCEPTEDLOC" 2> /dev/null
if [ $? -ne 0 ]; then echo ERROR: Unable to change directory to $ACCEPTEDLOC; exit 1; fi
# Consider all JPEGs in this directory
for f in *.jpg; do
cr2="${f%%jpg}cr2" # Replace "jpg" extension with "cr2"
echo Processing \"$f\", looking for \"$cr2\"...
find "$CR2LOCATION" -iname "$cr2" -not -path "$ACCEPTEDLOC" -exec cp "{}" . \; 2> /dev/null
done
Then, start the Terminal application, and do the following just one time before use in order to make the script executable:
cd Desktop
chmod +x GetCR2s.command
Now you should be able to save the images your client has accepted (by clicking Save Attachments in your Email program) into the Desktop/accepted folder, then simply double-click on the script GetCR2s.command on your Desktop and it will gather all the matching CR2 files into that folder for you.

Resources