A TypeScript command-line based image converter used to convert JPEG, PNG, GIF, TIFF, BMP, and SVG images to the web-optimized WebP format. It's primarily designed for use in pre-commit hooks.
npm install image-converter-cli
image-converter-cli -i <image-glob> [OPTIONS]...
ECMAScript
import { ImageConverter }
const argv = [
"node",
"image-converter",
"-i",
"<image-glob>",
"OPTION 1",
"OPTION 2",
"OPTION 3..."
];
/*
If using staged files, populate .image-converter-temp/.staged_files
If using exclusions file, populate .image-converter-temp/.converter_exclusions
*/
const imageConverterObj = new ImageConverter(argv);
await imageConverterObj.runProgram();
CommonJS and ECMAScript using a dynamic import
(async () => {
const { imageConverter } = await import("ImageConverter");
const argv = [
"node",
"image-converter",
"-i",
"<image-glob>",
"OPTION 1",
"OPTION 2",
"OPTION 3..."
];
/*
If using staged files, populate .image-converter-temp/.staged_files
If using exclusions file, populate .image-converter-temp/.converter_exclusions
*/
const imageConverterObj = new ImageConverter(argv);
await imageConverterObj.runProgram();
})();
Example of command-line use in a POSIX shell script (Apache-2.0 License)
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
reject_commit=0
code_change=0
converterDir=./.image-converter-temp
bold=$(tput bold)
red=$(tput setaf 1)
redbg=$(tput setab 1)
green=$(tput setaf 2)
blue=$(tput setaf 4)
bluebg=$(tput setab 4)
yellow=$(tput setaf 3)
cyan=$(tput setaf 6)
normal=$(tput sgr0)
mkdir -p "$converterDir/"
git diff --name-status --staged --diff-filter=AMR | awk -F '\t' '$1 ~ /(A|M)/ {print $2}; $1 ~ /R100/ {print $3};' > "$converterDir/.staged_files"
sed -e '/^[[:blank:]]*#.*$/d' -e '/^[[:blank:]]*$/d' "./.converterignore" > "$converterDir/.converter_exclusions"
image-converter -i './{src,public}/**/*.(jpeg|jpg|jpe|jif|jfif|jfi|png|gif|tiff|tif|bmp|webp|heif|heifs|heic|heics|avci|avcs|avif|avifs)' -c './{src,public}/**/*.(js|vue|html)'
rm -f "$converterDir/.staged_files" "$converterDir/.converter_exclusions"
if [ -e "$converterDir/.conversion" ]; then
printf "\n%s\n" "${blue}Searching for non-WebP image extensions in code files...${normal}"
rm -f "$converterDir/.conversion"
current_date=$(date +"%Y-%m-%d_%H:%M:%S")
mkdir -p "./.image_backup/$current_date"
while read -r imagePath; do
git restore --staged "$imagePath"
mv -- "$imagePath" "./.image_backup/$current_date"
done < "$converterDir/.converted_source_image_files"
if [ -e "$converterDir/.code_search_files" ]; then
sed -i.bak -E 's/[^a-zA-Z 0-9]/\\&/g' "$converterDir/.converted_source_image_files"
rm -f "$converterDir/.converted_source_image_files.bak"
while read -r imagePath; do
basename="${imagePath##*/}"
filenameTemp="${basename%.*}"
filename="${filenameTemp%\\}"
ext="${basename##*.}"
while read -r codePath; do
sed -i.bak -E "s/($filename).$ext/\1\.webp/g w $converterDir/.changes" "./$codePath"
if [ -s "$converterDir/.changes" ]; then
printf "%s\n\n" "${cyan}Updated $codePath${normal}"
if [ $code_change -eq 0 ]; then
mkdir -p "./.code_backup/$current_date"
code_change=1
fi
mv -- "./$codePath.bak" "./.code_backup/$current_date/${codePath##*/}"
else
rm -f "./$codePath.bak"
fi
done < "$converterDir/.code_search_files"
done < "$converterDir/.converted_source_image_files"
fi
rm -f "$converterDir/.converted_source_image_files" "$converterDir/.converted_target_image_files" "$converterDir/.code_search_files" "$converterDir/.changes"
if [ $code_change -eq 1 ]; then
if ! [ -e "$converterDir/.converter_errors" ]; then
printf "%s\n" "${green}Successfully converted images and changed their references in code.${normal}"
else
printf "%s\n" "${green}Successfully converted some images and changed their references in code.${normal}"
fi
printf "\n%s\n%s\n\n" "${cyan}Original image files located at:" "$PWD/.image_backup/$current_date/${normal}"
printf "\n%s\n%s\n\n" "${cyan}Original code files located at:" "$PWD/.code_backup/$current_date/${normal}"
printf "%s\n" "${bold}${bluebg}Review the converted images/code changes and re-commit.${normal}"
printf "%s\n" "${bold}${blue}Use \"git diff\" to examine changes.${normal}"
else
printf "%s\n" "${yellow}No code files need updating.${normal}"
if ! [ -e "$converterDir/.converter_errors" ]; then
printf "\n%s\n" "${green}Successfully converted images.${normal}"
else
printf "\n%s\n" "${green}Successfully converted some images.${normal}"
fi
printf "\n%s\n%s\n\n" "${cyan}Original image files located at:" "$PWD/.image_backup/$current_date/${normal}"
printf "%s\n" "${bold}${bluebg}Review the converted images and re-commit.${normal}"
fi
reject_commit=1
fi
if [ -e "$converterDir/.converter_errors" ]; then
printf "\n%s\n" "${bold}${red}Errors occured:${normal}"
while read -r errorImagePath; do
printf "%s\n" "${red}$errorImagePath${normal}"
git restore --staged $errorImagePath
done < "$converterDir/.converter_errors"
printf "%s\n\n" "${bold}${redbg}Fix errors and re-commit.${normal}"
rm -f "$converterDir/.converter_errors"
reject_commit=1
fi
rm -rf "$converterDir/"
if [ $reject_commit -eq 1 ]; then
exit 1
else
npx pretty-quick --staged
npm run lint
# Do anything else that normally would occur in the pre-commit hook
fi
The root directory can contain a .converterignore, which uses the same syntax as .gitignore. The contents of this must be copied to .image-converter-temp/.converter_exclusions (with comments removed, if applicable) for the image converter to know about it.
A temporary folder, .image-converter-temp is created in the project's root directory. There are seven temporary files located within this directory to be used in the pre-commit hook:
A file created when a successful conversion happens.
Created only if the -c, --code-glob
option was used. Contains the code files that the code glob found. The pre-commit script can search for relevant extensions and replace them.
This file needs to be populated by your pre-commit script (if not overriden). POSIX shell example for getting all added, modified, and renamed files and copying them to .staged_files file within the temporary directory:
git diff --name-status --staged --diff-filter=AMR | awk -F '\t' '$1 ~ /(A|M)/ {print $2}; $1 ~ /R100/ {print $3};' > "./.image-converter-temp/.staged_files"
The contents of .converterignore should be copied to the image-conveter-temp directory by your pre-commit hook as .converter_exclusions (unless --override-excluded-files
is used). POSIX shell example that removes all comment lines which start with "#" in .converterignore and copies the output to .converter_exclusions file within the temporary directory:
sed -e '/^[[:blank:]]*#.*$/d' -e '/^[[:blank:]]*$/d' "./.converterignore" > "./.image-converter-temp/.converter_exclusions"
Contains the source images of successfully converted files.
Contains the successfully converted files.
Contains all images that experienced errors when converting.
Output the version number.
Glob to search image files.
Glob to search code files.
Process SVG files.
Don't exclude unstaged files.
Don't exclude files from exclusions list.
Create a PNG/GIF file if a JPEG, PNG, GIF, TIFF, or BMP file doesn't exist.
Display help for command.
image-converter -i './{src,public}/**/*.(jpeg|jpg|jpe|jif|jfif|jfi|png|gif|tiff|tif|bmp|webp|heif|heifs|heic|heics|avci|avcs|avif|avifs)' -c './{src,public}/**/*.(js|vue|html)'