How to Create a Macro to Automatically Optimize Downloaded Images in Keyboard Maestro

Hi everyone,

I'm looking for some assistance with creating a macro in Keyboard Maestro. I download images frequently to a specific folder, and currently, I manually right-click each file and select "ImageOptimize" to optimize the images.

I would like to automate this process. Ideally, I want a macro that automatically runs every file I download into this folder through ImageOptimize as soon as the download is complete.

Can anyone guide me on how to set this up? Any help with the steps or a sample macro would be greatly appreciated!

Thanks in advance for your help!

Have you checked out Hazel? It's made for this sort of thing.

If you don't want to use Hazel, here's a Keyboard Maestro macro that seems to work, with a couple caveats that you should note.

Download Macro(s): ImageOptim.kmmacros (17 KB)

Macro screenshot

Macro notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.
System information
  • macOS 14.5
  • Keyboard Maestro v11.0.3

This will handle one or more image files appearing in the Downloads folder. It worked well in my testing, but the caveats are as follows:

  • It may break for really massive image files, because sometimes the trigger (new file added) may fire before such a large file is actually downloaded. I have added a loop (which checks that the file size is no longer changing) to hopefully prevent that from happening, but it may still be an issue.
  • This macro fires every time anything is added to the downloads folder. It has to, because that's how the trigger works. To control when it actually tries to do anything with a download, I do a file extension check. Just set the green box to contain all the file extensions you'd like it to work on; anything other than those, and the macro will just quit.
  • The macro has to duplicate every image file added to Downloads. The duplicate is removed when done.

That last one needs a bit of explaining. Because ImageOptim optimizes files in place (overwrites the original), it uses temporary files while doing its processing. And it writes those temporary files to the same directory it's running in ... and those temporary files trigger the macro again, because they're newly added ... and when it overwrites the original file at the end, that also triggers the macro again!

I tried multiple ways (semaphore locks, disabling and re-enabling the macro) of avoiding this, but never had full success. The solutions I got working then limited the macro to only handling one added file within a few seconds of another, and I wanted it to work even if a dozen appeared almost simultaneously.

In the end, the solution was to copy the newly-added file to the /tmp folder, then run ImageOptim on the file in the /tmp folder. When it was done, I disable the macro, copy the file back to Downloads, then re-enable the macro.

Also, I'm using the command line interface to ImageOptim, as it's much simpler than trying to select a contextual menu item.

Try with some copies of files you add to Downloads to make sure this does what you want it to do.

-rob.

Wow, that was more complex than I had expected it would be. The one thing I'm wondering about is whether it's possible to change how the trigger works, which might solve some of the problems. The user said "I download images frequently to a specific folder" but I would inquire more about that process, because it's possible that the solution could keep an eye on the things he did to do the download, and to "monitor" when the process he used is completed, rather than trigger on the addition of a file to that folder.

I would also inquire about what his expectations are when he says "as soon as the download is complete." When he says "as soon as" maybe he would tolerate a 5 minute delay, which could provide opportunities for a solution.

For example, maybe the user is always downloading files manually with the mouse, and a macro might then be able to do the job by triggering on "5 minutes of inactivity." Or perhaps the file is downloaded by a process that appears in the background, and the trigger could then activate by monitoring when the process has disappeared. These ideas might eliminate the problem you faced for really massive image files.

Anyway, your solution is really good and I'm just pondering other ideas, as I often do. You put a lot of work into it.

Is there a temp file naming convention you can use to filter on? You get the same issue with Office files, but can get round it with "If %TriggerValue% contains ~$ Then Cancel this macro".

1 Like

Possibly—I'll admit I didn't look too closely, as I'd never used ImageOptim before. But might be worth investigating for the original poster. (Though if the files are small, the overhead of an extra copy isn't horrid.)

-rob.

I took a look, and it turns out I was already canceling on temp files. But when it rewrites the main file, it triggers the macro again. The only way I could get around it was by keeping a global variable that tracks already-processed files.

Download Macro(s): ImageOptim ver 2.kmmacros (18 KB)

Macro screenshot

Macro notes
  • Macros are always disabled when imported into the Keyboard Maestro Editor.
    • The user must ensure the macro is enabled.
    • The user must also ensure the macro's parent macro-group is enabled.
System information
  • macOS 14.5
  • Keyboard Maestro v11.0.3

But honestly, I'd use the first one, as it doesn't require a global and seems a bit more logical to my brain—even at the cost of extra disk transactions. (The new one also auto-deletes the tracking variable when it gets over a certain number of rows—this keeps the global small, at the cost of some reprocessing during the run that resets the variable.)

-rob.