How to output results of an AppleScript image resizing script and display in automator

applescriptautomator

I am currently using an automator flow that copies finder items, changes them to jpeg, reveals them, and then runs an applescript that presents a dialog for batch resizing by image width. Every now and then, the script misses a couple of files or I prematurely move them from the folder before they have finished. I added a couple of pieces to the automation to

  1. Set value of variable: output
  2. Ask for confirmation: output

This doesn't really output anything useful, but it does notify me when the script has finished running. Is there some way to output whether or not there were any issues with the script or is this way too crazy of a question to be asking on stackexchange? In advance… No, I'm not very familiar with AppleScript.

Here's the script – I appreciate any & all advice/help 🙂

tell application "System Events"
    activate
    set theWidth to display dialog "Enter the width" default answer "2000"
    set theWidth to the text returned of theWidth as real
end tell
global theWidth
tell application "Finder"
    set some_items to selection as list
    repeat with aItem in some_items
        set contents of aItem to aItem as alias
    end repeat
end tell
repeat with i in some_items
    try
        rescale_and_save(i)
    end try
end repeat

to rescale_and_save(this_item)
    tell application "Image Events"
        launch
        set the target_width to theWidth
        -- open the image file
        set this_image to open this_item
        
        set typ to this_image's file type
        
        copy dimensions of this_image to {current_width, current_height}
        if current_width is greater than target_width then
            if current_width is greater than current_height then
                scale this_image to size target_width
            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
        end if
        
        tell application "Finder"
            set file_name to name of this_item
            set file_location to (container of this_item as string)
            set new_item to (file_location & file_name)
            save this_image in new_item as typ
        end tell
    end tell
end rescale_and_save

Best Answer

Give this a try:

use scripting additions

global target_width
global selImgs, chgList -- list of selected images, list of scaled images
global ctr, imgCt -- processed image counter, progress bar image total

set selImgs to {}
set target_width to 2000
set chgList to {}

display dialog "Enter maximum width" default answer "2000"
set target_width to the text returned of result as integer

-- Close scaled list (if open from previous run)
tell application "TextEdit"
    if exists document "scaled.txt" then
        close document "scaled.txt"
    end if
end tell

-- Selected images > list of alias
tell application "Finder"
    set selImgs to selection as alias list
end tell

-- construct progress bar
set imgCt to length of selImgs
set my progress total steps to imgCt
set my progress completed steps to 0
set ctr to 0
set my progress description to "Scaling images..."
set my progress additional description to "Preparing to process."

-- the horror…
repeat with ei in selImgs
    rescale_and_save(ei)
end repeat

-- Notification of changes (filenames if < 4, otherwise count)
considering application responses
    set AppleScript's text item delimiters to space
    if length of chgList > 4 then
        set imChg to length of chgList as text
    else
        set imChg to chgList as text
    end if
    display notification imChg with title "Images scaled"
end considering

-- Publish list of scaled images
set AppleScript's text item delimiters to return
set chText to chgList as text
set scFile to (((path to desktop) as text) & "scaled.txt") as «class furl»
close access (open for access scFile)
write chText to scFile as text
tell application "TextEdit"
    open scFile
    set bounds of front window to {30, 30, 300, 240}
end tell

-- the horror….
to rescale_and_save(this_file)
    tell application "Image Events"
        launch
        -- before each test run, I duplicate the images, so I won't have to re-fetch the originals
        if name of this_file contains "copy" then
            
            -- open the image file, increment progress bar
            set this_image to open this_file
            set ctr to (my progress completed steps) + 1
            set my progress additional description to "Scaling image " & ctr & " of " & imgCt
            set my progress completed steps to ctr
            
            -- process image (measure, scale, save, collect name)
            copy dimensions of this_image to {current_width, current_height}
            
            if current_width is greater than target_width then -- wide enough to process
                set txName to name of this_image as text
                
                if current_width is greater than current_height then -- when landscape
                    scale this_image to size target_width
                    save this_image with icon
                    copy txName to end of chgList
                    
                else -- when portrait
                    -- figure out new height
                    -- y2 = (y1 * x2) / x1
                    
                    -- NB as 'scale to size' requires integer, round up
                    set new_height to round (current_height * target_width / current_width) rounding up
                    scale this_image to size new_height
                    save this_image with icon
                    copy txName to end of chgList
                end if
            end if
            close this_image
        end if
    end tell
    
end rescale_and_save

Notes:

  • For looping through the files, it is simpler to make some_items a list of aliases

  • When scaling with size rather than factor, new_height should be integer

  • Save within if…then block, otherwise every selected file will be re-saved, even when not scaled

  • Use Image Events to save the files

  • If your folder is a subfolder of Pictures, you can enable 'Dimensions' in list view, which displays something like '2097 Ă— 3014', letting you see which images will be scaled. It doesn't update rapidly so it won't typically display the changed dimension, instead, it displays '--', which at least has the virtue of identifying which files have been changed.

  • Progress bar

  • Track scaled images and raise a notification when done, as well as create a text file log on desktop

  • Optional: Have a dry run script — tests each image's dimensions and reports back (e.g. count of images to be scaled, filenames of images to be scaled). You could even have it change the selection to only those files in the Finder when complete. Then when you run the final script, it will be clear which files will change.

FWIW, I tried using factor to scale but I found that after working for a while, it became erratic, and would often lock up the script (and overheat my mac, and require me to manually quit sips). I grew bored of that and used size (but with forcing new_height to be an integer). After that change, it became more reliable. You may find the tracking unnecessary.