Automated Screenshot loop with lowlevel Compression

Want to create endless screenshoot automation with following image compression.

first part, no beauty, but works
the compression won’t…
what am I doing wrong?


repeat
	set _date to do shell script "date -n +%y-%m-%d"
	set _time to do shell script "date +%H.%M.%S"
	set _folder to ("/Users/***/Pictures/ScreenLine/" & _date) -- ***=user
	
	do shell script ("mkdir -p " & _folder)
	set _image to do shell script ("screencapture -t jpg -x " & _folder & "/" & _date & "_" & _time & "_ScreenLine" & ".jpg“)
--
	tell application "Image Events" to launch
	repeat with _resize in _image
		tell application "Image Events"
			try
				save _resize with compression level low
				close _resize
			end try
		end tell
	end repeat
--
	delay 60
end repeat

v ScreenLine
> 18-12-22
v 18-12-23
18-12-23_11.08.35_ScreenLine.jpg
18-12-23_11.08.49_ScreenLine.jpg
18-12-23_11.08.54_ScreenLine.jpg
18-12-23_11.11.53_ScreenLine.jpg
18-12-23_11.13.52_ScreenLine.jpg

You have the following line in your script:

set _image to do shell script ("screencapture -t jpg -x " & _folder & "/" & _date & "_" & _time & "_ScreenLine" & ".jpg“)

Immediately after this line, insert the following:

return _image

This will terminate the script at that point, whilst also returning the value that gets stored in the variable _image, which will appear in the result’s pane at the bottom of Script Editor.

I haven’t test your script, but I do know that the shell command screencapture doesn’t return any output to stdout. Therefore, I’m guessing you’ll probably find that your variable _image contains an empty string, “”. If so, that’ll be a big part of why the second half of your script doesn’t do anything.

People have different ways of debugging their scripts to isolate where problems originate. I tend to laboriously insert return %some var% statements after lines I want to investigate to obtain the value of some variable. It’s not the best method, but old habits die hard. Other people choose to display dialogs at various points in their script to get a glimpse of the contents of a variable whilst allowing execution of the script to continue. Then there’s the excellent Script Debugger by Late Night Software, which not only keeps an itemised list of variables along with their values at the end of a script’s run for you to peruse, but also has a fully-fledged debug mode that allows step-by-step line execution of a script and examination of variables and expressions at any given point.

Another thing you can do is get rid of your try and end try statements, because there’s no need for them in the way that you’ve got it currently set up. All it’s done, unfortunately, is stopped an error from terminating your script, which—had it not done so—would have allowed the error to be caught, thus terminating your script and reporting to you the reason why:

error "Image Events got an error: Can’t make \"\" into type specifier." number -1700 from "" to specifier

which I just got by running the command

tell application "Image Events" to save "" with compression level low

[ EDIT: Actually, this isn’t quite true, since you have a repeat loop (the inner one) that I just realised won’t ever be entered because _image will be an empty string, which has nothing to loop over. So the script wouldn’t have thrown an error; it would simply run to the end (and then repeat again because of your outer loop). Nonetheless, still a good idea to remove the try statement anyway. ]

Hi. Welcome to MacScripter.

As CK’s pointed out, the screencapture shell script returns an empty string, so you need to use the script’s existing knowledge of the file path to get at the file. You also need to open the file as a document in Image Events before you can do anything to the image.

Presumably you intend the script to run as an application in the background while you do other things. This is difficult to script sensibly. The normal way would be to use a script with an idle handler, the script being saved as a stay-open application. The system would automatically call the handler at the specified interval until the application was quit. However, the intervals aren’t particularly accurate on my machine. Using a repeat like yours with a delay seems to produce more accurate intervals, but then the script application has to be force-quit when you’ve finished with it. Applications don’t quit in the normal way until they’ve finished what they’re doing, which in this case is running an infinitely repeating script.

Here’s the idle approach. The script has to be saved as a stay-open application. (Select “Application” in the “File Format:” menu at the bottom of the “Save As…” dialog and check the “Stay open after run handler” option.)

on run
	-- Launch Image Events prior to doing anything else.
	tell application "Image Events" to launch
end run

-- This handler's called by the system: intially immediately and then after the number of seconds it returns at the end.
on idle
	-- Create date and time strings using a faster method than a shell script — faster than two shell scripts, even!
	set now to (current date)
	set {year:y, month:m, day:d, hours:hr, minutes:min, seconds:sec} to now
	tell (y * 10000 + m * 100 + d) as text to set _date to text 3 thru 4 & "-" & text 5 thru 6 & "-" & text 7 thru 8
	tell (1000000 + hr * 10000 + min * 100 + sec) as text to set dateTime to _date & "_" & text 2 thru 3 & "." & text 4 thru 5 & "." & text 6 thru 7
	-- Create the paths for the container folder and the JPG file.
	set ScreenLinePath to (POSIX path of (path to pictures folder)) & "ScreenLine/"
	set _folder to ScreenLinePath & _date
	set fullPath to _folder & "/" & dateTime & "_ScreenLine.jpg"
	-- Do the mkdir and screen capture commands in the same shell script.
	do shell script ("mkdir -p " & _folder & "; screencapture -t jpg -x " & fullPath)
	
	-- Open the JPG file in Image Events and resave the document to the same file with a low compression level.
	set imageFile to POSIX file fullPath
	tell application "Image Events"
		set _resize to (open imageFile)
		save _resize with compression level low
		close _resize
	end tell
	
	-- Tell the system to call this handler again roughly 60 seconds after the previous call, allowing for the time taken to execute the screenshot code.
	return 60 - ((current date) - now)
end idle

-- When this script app gets a signal to quit, quit Image Events too.
on quit
	tell application "Image Events" to quit
	continue quit
end quit

And here’s the repeating version. Save this as an application as above, but leave the “Stay open after run handler” option unchecked.


-- NB. This script applet will need to be force-quit when you've finished with it.

main()

on main()
	-- Launch Image Events prior to doing anything else.
	tell application "Image Events" to launch
	
	repeat
		-- Create date and time strings using a faster method than a shell script — faster than two shell scripts, even!
		set now to (current date)
		set {year:y, month:m, day:d, hours:hr, minutes:min, seconds:sec} to now
		tell (y * 10000 + m * 100 + d) as text to set _date to text 3 thru 4 & "-" & text 5 thru 6 & "-" & text 7 thru 8
		tell (1000000 + hr * 10000 + min * 100 + sec) as text to set dateTime to _date & "_" & text 2 thru 3 & "." & text 4 thru 5 & "." & text 6 thru 7
		-- Create the paths for the container folder and the JPG file.
		set ScreenLinePath to (POSIX path of (path to pictures folder)) & "ScreenLine/"
		set _folder to ScreenLinePath & _date
		set fullPath to _folder & "/" & dateTime & "_ScreenLine.jpg"
		-- Do the mkdir and screen capture commands in the same shell script.
		do shell script ("mkdir -p " & _folder & "; screencapture -t jpg -x " & fullPath)
		
		-- Open the JPG file in Image Events and resave the document to the same file with a low compression level.
		set imageFile to POSIX file fullPath
		tell application "Image Events"
			set _resize to (open imageFile)
			save _resize with compression level low
			close _resize
		end tell
		
		-- Wait until 60 seconds after the previous call, allowing for the time taken to execute the screenshot code.
		delay 60 - ((current date) - now)
	end repeat
end main

Thanks for the friendly reception, I am pleased to be here.

The solution to set the path via posix is great. What I don’t quite understand is the conversion of date/time, is there certain reason?

the matter with force still does not bother, was already before. Maybe find something for the repeat.

The script has become a lot bigger, thanks a lot for the work!!