I have an interest in an applescript that will convert a folder of jpeg images from their original size to 72 dpi versions at 2" wide without the use of Photoshop. My question is whether anyone has utilized any of the available tools (ie. Kazu’s Extra Suites, Image Events, GraphicConverter, or others?) and have a tool to recommend based on performance & flexibility?
Scott:
I have not had the need to do anything that specific, but supposedly, iMagine Photo is your best bet.
Thank you… I have read some interesting information re: imaginePhoto… I did write a script using Image Events earlier and was going to give imagine a speed test later on. If I determine a significant speed difference, I will report my findings. (But, if anyone else has had any experience, feel free to chime in!)
I was trying to batch scale down some images with Image Events, only to find that a) it’s slow and worse, b) there’s no way to reduce quality. So I took a shot at iMagine Photo. It looks amazing, and I thank ktam for it. Unfortunately its power makes it way more complicated that I really need. I could spend a couple hours studying the manual, or maybe somebody with more experience could tell me how to convert this to iMagine Photo syntax, with the addition of a quality reduciton:
on rescale_and_save(this_item)
tell application "Image Events"
launch
-- open the image file
set this_image to open this_item
set typ to this_image's file type
if themethod is "Pixels" then
set target_width to theValue
copy dimensions of this_image to {current_width, current_height}
if current_width is greater than current_height then
scale this_image to size target_width
else
set the new_height to (current_height * target_width) / current_width
scale this_image to size new_height
end if
else if themethod is "Percentage" then
scale this_image by factor theValue
end if
save this_image as typ
end tell
end rescale_and_save
here theMethod is set with a dialog; theValue is set in pixels if theMethod is “Pixels” and as a factor (ie, 0.5) if theMethod is Percentage (ie, 50). the_item is an HFS path as a string.
Ideally I would also like to:
- revert to Image Events if iMagine Photo is not installed (is there a way to check if an application is installed and can be “told” without checking the processes first??)
- run iMagine Photo as a background application.
PS: I notice that in the example droplets, there is a property:
property myLib : load script (alias “/Applications/iMagine Photo/AppleScriptLib/Subroutines”)
This depends on the iMagine Photo folder being kept in /Applications. Shouldn’t this be relative to the application’s actual location instead?
This might be better:
property idtype : "kASD"
tell application "Finder" to set IPpath to container of (application file id idtype as alias) as string
set myLib to load script (IPpath & "AppleScriptLib:Subroutines") as string
Thanks.
i really like the netpbm package availible via fink.
as simple as and really powerfull you can do anything almost.
jpegtopnm DSC00088.JPG | pnmscale --height 200 --width 200 | pnmtojpeg > one.jpg
thanks for the suggestion. but i want something that your average end user can install – so if it involves fink it’s probably no good.
Using iMagine Photo I think the following script will do what you want.
Kevin
using terms from application "iMagine Photo"
property exportQuality : low
end using terms from
property themethod : "Pixels"
property target_width : 144
property theValue : 0.4 -- not percentage.
on run
set thisFile to choose file
my rescale_and_save(thisFile)
end run
on rescale_and_save(this_item)
tell application "iMagine Photo"
launch
set thisImporter to import graphic this_item
if the component error of thisImporter is equal to 0 then
my CreateReplacingExporterLikeImporter(thisImporter)
if themethod is "Pixels" then
set {x, y, current_width, current_height} to the natural bounds of thisImporter
set theScale to target_width / current_width
else
set theScale to theValue
end if
set the scale of thisImporter to {theScale, theScale}
set the export compression quality of thisImporter to exportQuality
export thisImporter
end if
close thisImporter
end tell
end rescale_and_save
on CreateReplacingExporterLikeImporter(theInitialImporter)
tell application "iMagine Photo"
try
tell theInitialImporter
set theImporterType to the graphic type
set exportType to my GetExportTypeFromImportType(theImporterType)
make exporter with properties {export file type:exportType}
if the export component error is not equal to 0 then
set the export file type to "TIFF"
end if
set export file location to file location as alias
end tell
end try
end tell
end CreateReplacingExporterLikeImporter
on GetExportTypeFromImportType(theimportType)
if theimportType is equal to "Photo - JPEG" then
return "JPEG"
else if theimportType contains "TIFF" then
return "TIFF"
else if theimportType is equal to "QuickDraw" then
return "PICT"
else if theimportType is equal to "Planar RGB" then
return "Photoshop"
else if theimportType is equal to "JPEG 2000" then
return "JP2"
else
return theimportType
end if
end GetExportTypeFromImportType
If you have any problems let me know.
Kevin
Thanks a lot! I had already dove in and got something workable, but without fully understanding how. But your solution is much more elegant than mine was, which used a lot of unnecessary parts of your subroutines that I didn’t understand, and separate handlers for scaling and setting image size.
You left out two things though which are important here : 1) ability to revert to using image events if iMagine isn’t installed and 2) setting image quality if it is.
With regards to 2 above, I wonder why iMagine doesn’t just use a quality value instead of named properties. But at any rate it can be handled.
One other comment/feedback on the subroutines: Please see what I said above about needing to have iMagine folder in the /Applications folder to work. A better solution would be to use something like I did above. Even better would be to put the essential subroutines inside the iMagine package, so it can be accessed with path to scripts folder of …
Anyway here’s my modified solution, hope it is usefull generally:
property default_method : "Percentage"
-- options would be "No Scale", "Percentage", "Pixels"
property default_target_width : "320"
property default_scale : "40"
property default_qual : "Medium"
property export_options : {"Minimum", "Low", "Medium", "High", "Maximum", "Lossless"}
property iptype : "kASD"
property ipName : "iMagine Photo"
property hasip : false
global themethod, theValue, exportQuality
on run
-- normally setting defaults handled in run handler, with better error checking
set default_method to button returned of (display dialog "How do you want to scale images?" buttons {"No Scale", "Pixels", "Percentage"} default button default_method)
if default_method is "Pixels" then
set default_target_width to text returned of (display dialog "Scale images to a target width of how many pixels?" default answer default_target_width)
else if default_method is "Percentage" then
set default_scale to text returned of (display dialog "Scale images to what percentage?" default answer default_scale)
end if
set hasip to my appExists(ipName, iptype)
if hasip then
set thereply to choose from list export_options with prompt "Choose an export quality:" with title "JPG Quality" default items default_qual without multiple selections allowed and empty selection allowed
if thereply is not false then set default_qual to item 1 of thereply
end if
-- normally this would be part of an open handler
set themethod to default_method
if themethod is "Pixels" then
set theValue to default_target_width as number
else if themethod is "Percentage" then
set theValue to (default_scale as number) / 100
else
set theValue to 0
end if
set hasip to my appExists(ipName, iptype)
if hasip then
using terms from application "iMagine Photo"
tell application ipName
if default_qual is "Minimum" then
set exportQuality to minimum
else if default_qual is "Low" then
set exportQuality to low
else if default_qual is "Medium" then
set exportQuality to medium
else if default_qual is "High" then
set exportQuality to high
else if default_qual is "Maximum" then
set exportQuality to maximum
else
set exportQuality to lossless
end if
end tell
end using terms from
end if
set thisFile to (choose file) as string
-- thisFile stored as a string as needed by image events, converted to alias below for iMagine
my rescale_and_save(thisFile)
end run
on rescale_and_save(this_item)
if themethod is not "No Scale" then
if hasip then
using terms from application "iMagine Photo"
tell application ipName
launch
set thisImporter to import graphic (this_item as alias)
if the component error of thisImporter is equal to 0 then
my CreateReplacingExporterLikeImporter(thisImporter)
if themethod is "Pixels" then
set {x, y, current_width, current_height} to the natural bounds of thisImporter
set theScale to theValue / current_width
else
set theScale to theValue
end if
set the scale of thisImporter to {theScale, theScale}
set the export compression quality of thisImporter to exportQuality
export thisImporter
end if
close thisImporter
end tell
end using terms from
else
tell application "Image Events"
launch
-- open the image file
set this_image to open this_item
set typ to this_image's file type
if themethod is "Pixels" then
copy dimensions of this_image to {current_width, current_height}
if current_width is greater than current_height then
scale this_image to size theValue
else
-- figure out new height
-- y2 = (y1 * x2) / x1
set the new_height to (current_height * target_width) / current_width
scale this_image to size new_height
end if
else if themethod is "Percentage" then
scale this_image by factor theValue
end if
save this_image as typ
end tell
end if
end if
end rescale_and_save
on CreateReplacingExporterLikeImporter(theInitialImporter)
using terms from application "iMagine Photo"
tell application ipName
try
tell theInitialImporter
set theImporterType to the graphic type
set exportType to my GetExportTypeFromImportType(theImporterType)
make exporter with properties {export file type:exportType}
if the export component error is not equal to 0 then
set the export file type to "TIFF"
end if
set export file location to file location as alias
end tell
end try
end tell
end using terms from
end CreateReplacingExporterLikeImporter
on GetExportTypeFromImportType(theimportType)
if theimportType is equal to "Photo - JPEG" then
return "JPEG"
else if theimportType contains "TIFF" then
return "TIFF"
else if theimportType is equal to "QuickDraw" then
return "PICT"
else if theimportType is equal to "Planar RGB" then
return "Photoshop"
else if theimportType is equal to "JPEG 2000" then
return "JP2"
else
return theimportType
end if
end GetExportTypeFromImportType
on appExists(appName, theid)
try
-- is it running?
tell application "System Events"
if (name of processes) contains appName then return true
end tell
-- is it in a standard location on the hard drive?
tell application "Finder"
--if exists file (appName & ".app") of (path to applications folder) then return true
--this should work regardless of whether the app name end in .app :
if exists file (appName) of (path to applications folder from system domain) then return true
if exists file (appName) of (path to applications folder from user domain) then return true
if exists file (appName) of (path to applications folder from local domain) then return true
end tell
-- can we get it by id type?
tell application "Finder"
if exists application file id theid then return true
end tell
return false
on error
return false
end try
end appExists
Wooden Brain,
hey Mr Brain are you the brainy one. sorry for the bad joke.
As to the script locations you have a point, but it is unlikely I’ll get around to doing it. My time for iMagine Photo is pretty limited these days.
One more thing though, you mentioned you wanted to have iMagine Photo run as a background application. You can control that.
you can find out if iMagine Photo is running in the background by using the following in an iMagine Photo block.
set isBackground to run in background
You can tell iMagine Photo to run as a background only app next time it runs by doing the following
set run in background to true
You can also set a quit delay which means that iMagine Photo when running as a background only application will quit automatically if there is no requests of it and there are no objects still open after a set amount of time. For example the following will tell iMagine Photo to quit after 10 seconds if running as a background only application. iMagine Photo does not remember the quit delay setting between each time it runs.
set quit delay to 10
You can add a small section to your script to set this the first time your script runs iMagine Photo.
tell application "iMagine Photo"
launch
if run in background is false then
set run in background to true
quit
do shell script "sleep 3"
launch
end if
end tell
Kevin