Code block of the script in question.

background remover bash script

Here's a very simple Bash script that can remove all image backgrounds in folder full of files.

It depends on the amazing work of Johnatan Nader:

BackgroundRemover

#!/bin/bash

# depends on
# https://github.com/nadermx/backgroundremover

# escape bad filenames
IFS="$(printf '\n\t')"
controlchars="$(printf '*[\001-\037\177]*')"

wd="$(pwd)"

# bash array
files=( $(find . -type f ! -name "$controlchars" -iname "*.png" -o -iname "*.jpg" -o -iname "*.jpeg" -iname "*.JPG") )
#echo "$files"

# no error if directory exists and creates parents
mkdir --parents "$wd"/bg-removed

i=$(echo "${#files[@]}" | bc)
for ((x=0; x < i; x++)); do
	echo "Processing ${files[x]}"
	
	# can't operate on the same file it has to create a copy
	backgroundremover -i "${files[x]}" -o "${files[x]}-nobg.png"
	mv "${files[x]}-nobg.png" "$wd/bg-removed/${files[x]}-nobg.png"
done

The arcane invocations at the beggining are there to escape bad filenames. It technically isn't neccesary but it is a good practice to include it in our bash scripts so we don't process malicious files that we downloaded from the internet by mistake.

Next we store the current directory with: wd="$(pwd)". We will be creating a folder where we will put all of our newly created images without backgrounds, so we need to append this string later.

Afterwards we find all our files that we want to process with the find command.

The arguments are:

  • . For finding files in the current directory.
  • -type f For returning only regular files.
  • ! -name "$controlchars" For excluding files with bad filenames.
  • -iname "*.png" -o -iname "*.jpg" -o -iname "*.etc" For processing only the file extensions that we want.

Then we loop in the array created with the syntax files=( $(find) ). But first we need to know how many elements it contains, for that we can use the bashism ${#files[@]} that returns the number of elements in the array. We pipe it into bc to format it into an integer.

Inside the loop we can get the current element in the array using its index $files[x].

The syntax for backgroundremover is super simple. Just keep in mind that it can't overwrite the file that it is working on, so you need to output to a different filename. It also bugs out if you try to put that file in a subdirectory. So i just mv it when it is done.

With this you can get through hundreds of files in no time. It uses AI so it is pretty good, not perfect but it will get the job done 80% of the time. The rest you can fix it by hand.