Applescript to sips issues

So I have over 4000 images that I need to square, and I dont want to stretch them. I want to open the image, check the width or height, then use the largest value as a variable in sips.

here is my script so far

--Open image
set this_file to choose file without invisibles
tell application "Image Events"
	-- start the Image Events application
	launch
	-- open the image file
	set this_image to open this_file
	
	--Get width Height
	copy dimensions of this_image to {W, H}
	
	--What is the biggest?
	if W is greater than H then
		set padding_dimensions to H
	else
		set padding_dimensions to W
	end if
	
	--pass to sip 
	do shell script "/usr/bin/sips " & this_image & "-p " & padding_dimensions & padding_dimensions & " --padColor FFFFFF " & this_image
	
end tell

It runs right up to the sips bit. Then I get this error

I am sure I have do some POSIX stuff, but I am a bit stuck.

Cheers

  1. Classes
    To terminal you may send only text. So, you must convert it to text. Analyze first line of my script.

  2. Posix path.
    Even after conversion to text, the path notation is not readable by terminal sips or any shell program. You must convert it to POSIX notation. Analyze second line.

  3. Quoted form.
    If you send a text command to sips or any terminal program, be aware to spaces in paths. Just because, the spaces is used to separate parameters in command line. To avoid this, put the paths in quote. Analyze create sips command line.

  4. Spaces are necessary in commands
    In your scripts, the words: “& padding_dimensions & padding_dimensions” create one big number. Put spaces between with & operand: & padding_dimensions & " " & padding_dimensions &

  5. Return
    Last line of my script saves sips response to text variable. You may use this for error catching.

And, for readability, put sips commands outside the tell block.


Here is my working script:
set this_file to (choose file without invisibles) as text
set Posix_filepath to (POSIX path of this_file)
tell application "Image Events"
	-- start the Image Events application
	launch
	-- open the image file
	set this_image to open this_file
	
	--Get width Height
	copy dimensions of this_image to {W, H}
	
	--What is the biggest?
	if W is greater than H then
		set padding_dimensions to H
	else
		set padding_dimensions to W
	end if
	
end tell

-- create sips command. 
set sipscommand to "/usr/bin/sips " & quoted form of Posix_filepath & " -p " & padding_dimensions & " " & padding_dimensions & " --padColor FFFFFF " & quoted form of Posix_filepath

--pass to sip 

set sipsanswer to do shell script sipscommand as text

You are a champion!!!

Thanks so much its working just as I need it to

Hi.

  1. The script you posted actually uses the smaller dimension, not the larger!

  2. Image Events is essentially an AppleScript interface for sips. It provides a ‘pad’ command, so you could avoid multiple file-specifier types and the ‘do shell script’ overhead by staying with it:


set this_file to (choose file without invisibles)

tell application "Image Events"
	-- start the Image Events application
	launch
	-- open the image file
	set this_image to (open this_file)
	
	--Get width Height
	set {W, H} to dimensions of this_image
	
	--What is the biggest?
	if (W is greater than H) then
		set padding_dimensions to W
	else
		set padding_dimensions to H
	end if
	
	pad this_image to dimensions {padding_dimensions, padding_dimensions} with pad color {65535, 65535, 65535} -- Pad with white.
	save this_image -- This saves the edited image back to the original file, but it's possible to specify another destination.
	close this_image -- Close the image afterwards to clear it from memory.
	
	quit -- Quit Image Events afterwards for the same reason.
end tell

If you’ve got over 4000 images to process, you won’t want to run the script individually for each one, but repeat through a list of aliases between the ‘launch’ and ‘quit’ commands:


-- Somehow get a list of aliases to the image files. (Arrange this according to your own circumstances.)
set image_folder to (choose folder without invisibles)
tell application "Finder" to set image_files to (files of image_folder whose name ends with ".jpg") as alias list

tell application "Image Events"
	-- start the Image Events application
	launch
	
	repeat with this_file in image_files
		-- open the image file
		set this_image to (open this_file)
		
		--Get width Height
		set {W, H} to dimensions of this_image
		
		--What is the biggest?
		if (W is greater than H) then
			set padding_dimensions to W
		else
			set padding_dimensions to H
		end if
		
		pad this_image to dimensions {padding_dimensions, padding_dimensions} with pad color {65535, 65535, 65535} -- Pad out the smaller dimension with white.
		save this_image -- This saves the edited image back to the original file, but it's possible to specify another destination.
		close this_image -- Close the image afterwards to clear it from memory.
	end repeat
	
	quit -- Quit Image Events afterwards for the same reason.
end tell

beep 2
display dialog "Finished!" buttons {"OK"} default button 1 with icon note

Normally I’d agree, but this post suggests perhaps not:

macscripter.net/viewtopic.php?id=42631

Yugh! You’re right. And even my example Finder code for getting the list of aliases times out when there’s a really large number of files.

The version below incorporates weedinner’s ‘quit’ idea from the other thread, but only quits and relaunches Image Events after every tenth image processed. On my machine, it gets through a test folder of 6592 JPEGs in just over 36 minutes, including the time taken by the progress beeps:

on main()
	script o
		property image_paths : missing value
	end script
	
	-- Get a list of POSIX paths to the image files. (Arrange this according to your own circumstances.)
	set image_folder to (choose folder without invisibles)
	set o's image_paths to paragraphs of (do shell script ("find " & quoted form of POSIX path of image_folder & " \\( -type f  -name '*.jpg' \\)"))
	
	tell application "Image Events" to launch
	
	repeat with i from 1 to (count o's image_paths)
		set this_file to POSIX file (item i of o's image_paths)
		
		tell application "Image Events"
			-- open the image file
			set this_image to (open this_file)
			
			--Get width Height
			set {W, H} to dimensions of this_image
			
			--What is the biggest?
			if (W is greater than H) then
				set padding_dimensions to W
			else
				set padding_dimensions to H
			end if
			
			pad this_image to dimensions {padding_dimensions, padding_dimensions} with pad color {65535, 65535, 65535} -- Pad out the smaller dimension with white.
			save this_image -- This saves the edited image back to the original file, but it's possible to specify another destination.
			close this_image -- Close the image afterwards to clear it from memory.		
		end tell
		
		-- After every tenth image, beep to indicate progress and quit and relaunch Image Events.
		if (i mod 10 is 0) then
			beep
			tell application "Image Events" to quit
			tell application "System Events"
				repeat while (application process "Image Events" exists)
					delay 0.2
				end repeat
			end tell
			tell application "Image Events" to launch
		end if
	end repeat
	
	tell application "Image Events" to quit
end main

main()

This one, using a single ‘do shell script’ for each image instead of Image Events, is about four minutes faster with an identical folder:

on main()
	script o
		property image_paths : missing value
	end script
	
	-- Get a list of POSIX paths to the image files. (Arrange this according to your own circumstances.)
	set image_folder to (choose folder without invisibles)
	set o's image_paths to paragraphs of (do shell script ("find " & quoted form of POSIX path of image_folder & " \\( -type f  -name '*.jpg' \\)"))
	
	repeat with i from 1 to (count o's image_paths)
		set this_path to quoted form of item i of o's image_paths
		
		do shell script ("w=$(sips -g pixelWidth " & this_path & " | egrep -o '\\d+$');
h=$(sips -g pixelHeight " & this_path & " | egrep -o '\\d+$');
padding_dimensions=$(echo \"$w\\n$h\" | sort -n | sed -n '$ p');
sips -p $padding_dimensions $padding_dimensions --padColor FFFFFF " & this_path)
		
		if (i mod 10 is 0) then beep
	end repeat
end main

main()

I’m sure seasoned shell scripters will know a better way to identify the larger dimension than the sort-sed sequence I’ve used here, but I don’t know it myself. :wink:

Nigel, I have just used your script to resize and pad about 8000 images. It took about 15 mins!! Thanks so much!!