applescriptphotoshopinput-history

Why won't Photoshop revert to earlier history state in script?


I've written an Applescript to automate watermarking and resizing images for my company. Everything generally works fine — the script saves the initial history state to a variable, resizes the image, adds the appropriate watermark, saves off a jpeg, then reverts to the initial history state for another resize and watermark loop.

The problem is when I try not to use a watermark and only resize by setting the variable wmColor to "None" or "None for all". It seems that after resizing and saving off a jpeg, Photoshop doesn't like it when I try to revert to the initial history state. This is super annoying, since clearly a resize should count as a history step, and I don't want to rewrite the script to implement multiple open/close operations on the original file. Does anyone know what might be going on? This is the line that's generating the problem (it's in both the doBig and doSmall methods, and throws an error every time I ask it just to do an image resize and change current history state:

    set current history state of current document to initialState

and here's the whole script:

property type_list : {"JPEG", "TIFF", "PNGf", "8BPS", "BMPf", "GIFf", "PDF ", "PICT"}
property extension_list : {"jpg", "jpeg", "tif", "tiff", "png", "psd", "bmp", "gif", "jp2", "pdf", "pict", "pct", "sgi", "tga"}
property typeIDs_list : {"public.jpeg", "public.tiff", "public.png", "com.adobe.photoshop-image", "com.microsoft.bmp", "com.compuserve.gif", "public.jpeg-2000", "com.adobe.pdf", "com.apple.pict", "com.sgi.sgi-image", "com.truevision.tga-image"}
global myFolder
global wmYN
global wmColor
global nameUse
global rootName
global nameCount
property myFolder : ""

-- This droplet processes files dropped onto the applet 
on open these_items
    -- FILTER THE DRAGGED-ON ITEMS BY CHECKING THEIR PROPERTIES AGAINST THE LISTS ABOVE
    set wmColor to null
    set nameCount to 0
    set nameUse to null
    if myFolder is not "" then
        set myFolder to choose folder with prompt "Choose where to put your finished images" default location myFolder -- where you're going to store the jpgs
    else
        set myFolder to choose folder with prompt "Choose where to put your finished images" default location (path to desktop)
    end if

    repeat with i from 1 to the count of these_items
        set totalFiles to count of these_items
        set this_item to item i of these_items
        set the item_info to info for this_item without size
        if folder of the item_info is true then
            process_folder(this_item)
        else
            try
                set this_extension to the name extension of item_info
            on error
                set this_extension to ""
            end try
            try
                set this_filetype to the file type of item_info
            on error
                set this_filetype to ""
            end try
            try
                set this_typeID to the type identifier of item_info
            on error
                set this_typeID to ""
            end try
            if (folder of the item_info is false) and (alias of the item_info is false) and ((this_filetype is in the type_list) or (this_extension is in the extension_list) or (this_typeID is in typeIDs_list)) then
                -- THE ITEM IS AN IMAGE FILE AND CAN BE PROCESSED
                process_item(this_item)
            end if
        end if
    end repeat
end open

-- this sub-routine processes folders 
on process_folder(this_folder)
    set these_items to list folder this_folder without invisibles
    repeat with i from 1 to the count of these_items
        set this_item to alias ((this_folder as Unicode text) & (item i of these_items))
        set the item_info to info for this_item without size
        if folder of the item_info is true then
            process_folder(this_item)
        else
            try
                set this_extension to the name extension of item_info
            on error
                set this_extension to ""
            end try
            try
                set this_filetype to the file type of item_info
            on error
                set this_filetype to ""
            end try
            try
                set this_typeID to the type identifier of item_info
            on error
                set this_typeID to ""
            end try
            if (folder of the item_info is false) and (alias of the item_info is false) and ((this_filetype is in the type_list) or (this_extension is in the extension_list) or (this_typeID is in typeIDs_list)) then
                -- THE ITEM IS AN IMAGE FILE AND CAN BE PROCESSED
                process_item(this_item)
            end if
        end if
    end repeat
end process_folder

-- this sub-routine processes files 
on process_item(this_item)
    set this_image to this_item as text
    tell application id "com.adobe.photoshop"
        set saveUnits to ruler units of settings
        set display dialogs to never
        open file this_image
        if wmColor is not in {"None for all", "White for all", "Black for all"} then
            set wmColor to choose from list {"None", "None for all", "Black", "Black for all", "White", "White for all"} with prompt "What color should the watermark be?" default items "White for all" without multiple selections allowed and empty selection allowed
        end if
        if wmColor is false then
            error number -128
        end if
        if nameUse is not "Just increment this for all" then
            set nameBox to display dialog "What should I call these things?" default answer ("image") with title "Choose the name stem for your images" buttons {"Cancel", "Just increment this for all", "OK"} default button "Just increment this for all"
            set nameUse to button returned of nameBox -- this will determine whether or not to increment stem names 
            set rootName to text returned of nameBox -- this will be the root part of all of your file names
            set currentName to rootName
        else
            set nameCount to nameCount + 1
            set currentName to rootName & (nameCount as text)
        end if
        set thisDocument to current document
        set initialState to current history state of thisDocument
        set ruler units of settings to pixel units
    end tell
    DoSmall(thisDocument, currentName, initialState)
    DoBig(thisDocument, currentName, initialState)
    tell application id "com.adobe.photoshop"
        close thisDocument without saving
        set ruler units of settings to saveUnits
    end tell
end process_item

to DoSmall(thisDocument, currentName, initialState)
    tell application id "com.adobe.photoshop"
        set initWidth to width of thisDocument
        if initWidth < 640 then
            resize image thisDocument width 640 resample method bicubic smoother
        else if initWidth > 640 then
            resize image thisDocument width 640 resample method bicubic sharper
        end if
        set myHeight to height of thisDocument
        set myWidth to width of thisDocument
        if wmColor is in {"White", "White for all"} then
            set wmFile to (path to resource "water_250_white.png" in bundle path to me) as text
        else if wmColor is in {"Black", "Black for all"} then
            set wmFile to (path to resource "water_250_black.png" in bundle path to me) as text
        end if
        if wmColor is not in {"None", "None for all"} then
            open file wmFile
            set wmDocument to current document
            set wmHeight to height of wmDocument
            set wmWidth to width of wmDocument
            duplicate current layer of wmDocument to thisDocument
            close wmDocument without saving
            translate current layer of thisDocument delta x (myWidth - wmWidth - 10) delta y (myHeight - wmHeight - 10)
            set opacity of current layer of thisDocument to 20
        end if
        set myPath to (myFolder as text) & (currentName) & "_640"
        set myOptions to {class:JPEG save options, embed color profile:false, quality:12}
        save thisDocument as JPEG in file myPath with options myOptions appending lowercase extension
        set current history state of current document to initialState
    end tell
end DoSmall

to DoBig(thisDocument, currentName, initialState)
    tell application id "com.adobe.photoshop"
        set initWidth to width of thisDocument
        if initWidth < 1020 then
            resize image thisDocument width 1020 resample method bicubic smoother
        else if initWidth > 1020 then
            resize image thisDocument width 1020 resample method bicubic sharper
        end if
        set myHeight to height of thisDocument
        set myWidth to width of thisDocument
        if wmColor is in {"White", "White for all"} then
            set wmFile to (path to resource "water_400_white.png" in bundle path to me) as text
        else if wmColor is in {"Black", "Black for all"} then
            set wmFile to (path to resource "water_400_black.png" in bundle path to me) as text
        end if
        if wmColor is not in {"None", "None for all"} then
            open file wmFile
            set wmDocument to current document
            set wmHeight to height of wmDocument
            set wmWidth to width of wmDocument
            duplicate current layer of wmDocument to thisDocument
            close wmDocument without saving
            translate current layer of thisDocument delta x (myWidth - wmWidth - 16) delta y (myHeight - wmHeight - 16)
            set opacity of current layer of thisDocument to 20
        end if
        set myPath to (myFolder as text) & (currentName) & "_1020"
        set myOptions to {class:JPEG save options, embed color profile:false, quality:12}
        save thisDocument as JPEG in file myPath with options myOptions appending lowercase extension
        set current history state of current document to initialState
    end tell
end DoBig

Solution

  • If you choose a color : save document "Ducky.tif" as JPEG in file ..... the current document will be document "Ducky.tif".

    If you choose "None" or "None for all" : save document "Ducky.tif" as JPEG in file ...... the current document will be document "image_640".

    So the variable initialState = history state 2 of document "Ducky.tif" give an error, because this document no longer exists.

    To leaving original open, here's a solution , use copying true in your save command.

    save thisDocument as JPEG in file myPath with options myOptions appending lowercase extension with copying