MacOS – Batch convert BMP to both TIFF and JPEG, then have the converted images moved into respective folders

applescriptautomatormacos

I'm trying to modernise a film scanning workflow and need some guidance on how to automate my tasks more efficiently.

So let me first describe the situation and workflow that I need.

The film scanner produces a folder named after the Job Number (eg 2021_1234) with the actual film scans (.bmp) alongside cache/metadata files that are of no use at all (shown here as .xx and .zz). A sample directory is as follows:

~/2021_1234/
    01.xx
    02.xx
    03.xx
    01.zz
    02.zz
    03.zz
    01.bmp
    02.bmp
    03.bmp

I need the final result to follow this structure:

~/2021_1234/
    /2021_1234-TIFF/
        01.tiff
        02.tiff
        03.tiff
    /2021_1234-JPEG/
        01.jpg
        02.jpg
        03.jpg

Essentially the useless metadata files need to be deleted, and the .bmp files need to be converted to both .tiff and .jpeg files in their own subfolders with the Job Number as well.

Ideally I would like to also include LZW compression for the .tiff conversion if possible.

Currently I'm using a combination of manual copy/paste/delete, alongside 2 Automator Applications, 1 each for .jpeg and .tiff conversion. I'm only using a basic Get Specified Finder Items along with Change Type of Images.

It works, but it's not perfect as lots of manual steps still need to be done. Especially when I have to repeat all the steps for multiple jobs.

The ideal solution would allow me to simply drag 1 or multiple Job folders into an Automator Application and have it do all the image conversion, subfolder creation, and deletion of unnecessary files without any intervention on my end.

However, I can't seem to find a way to get the other steps done within Automator, and I get quite confused when I look at sample bash scripts that use sips. Many of the solutions I've seen online only solve one part of the problem that I'm facing (eg, just the image conversion, or just the folder creation), and I'm having trouble understanding the scripting language properly to combine them all together.

Any help with this would be greatly appreciated.

Thank you

Best Answer

The example shell script code, shown below, can be used as an Automator workflow created as either an Application or Service/Quick Action, using a Run Shell Script action with setting Pass input: [as arguments] and replacing the default code with it, as shown in the images further below.

For each folder dropped on the Automator workflow created as an Application, the example shell script code does the following:

  • Changes directory into the dropped folder.
  • Deletes the .xx and .zz files within.
  • Makes the Job Number-JPEG and Job Number-TIFF folders,
    e.g., 2021_1234-JPEG and 2021_1234-TIFF.
  • Creates a .jpg type file and .tiff type file of each .bmp type file into their respective folders.
for dir in "$@"; do

    [ -d "${dir}" ] || continue
    [ -w "${dir}" ] || continue
    cd "${dir}" || exit
    rm *.xx *.zz
    dn="${dir##*/}"
    mkdir -p "${dn}-JPEG" "${dn}-TIFF"

    for file in *.bmp; do
        sips --setProperty format jpeg "${file}" -o "${dn}-JPEG/"
        sips --setProperty format tiff --setProperty formatOptions lzw "${file}" -o "${dn}-TIFF/"
    done

done

To use the example shell script code as an Automator workflow created as a Service/Quick Action, set Workflow receives current [folders] in [Finder], as shown in the second image below.

Then in Finder, select the target folder(s) and right-click selecting the Service/Quick Action from the Services context menu.


Understanding the shell script:

  • for dir in "$@"; do -- For each folder dropped or selected, do the following:
  • [ -d "${dir}" ] || continue -- Makes sure the Finder item dropped or selected is a directory, or continue with the next item.
  • [ -w "${dir}" ] || continue -- Makes sure the Finder item dropped or selected is writable, or continue with the next item.
  • cd "${dir}" || exit -- Changes directory to the dropped or selected folder, or exits the shell script to avoid erroneous processing of remaining code.
  • rm *.xx *.zz -- Deletes all .xx and .zz files within the "${dir}" directory.
  • dn="${dir##*/}" -- Uses shell parameter expansion to get the directory name portion of the fully qualified pathname of the folder dropped or selected. Not actually necessary and could have just used "${dir##*/}" through the rest of the code, however, I believe it makes the remaining code easier to read.
  • mkdir -p "${dn}-JPEG" "${dn}-TIFF" -- Makes the Job Number-JPEG and Job Number-TIFF directories, e.g., 2021_1234-JPEG and 2021_1234-TIFF.
  • for file in *.bmp; do -- For each .bmp type file do the following:
  • sips --setProperty format jpeg "${file}" -o "${dn}-JPEG/" -- Create a .jpg type file of each .bmp type file into the Job Number-JPEG, e.g., 2021_1234-JPEG directory.
  • sips --setProperty format tiff --setProperty formatOptions lzw "${file}" -o "${dn}-TIFF/" -- Create a .tiff type file of each .bmp type file, with the requested LZW compression, into the Job Number-TIFF, e.g., 2021_1234-TIFF directory.


Automator workflow as an Application

Automator workflow as a Service/Quick Action