From 6204b5f7b31908427b01f0bd2a44b37a7c4f475d Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Thu, 21 Sep 2023 09:32:58 -0400 Subject: [PATCH] Added mktrans to scripts --- scripts/scripts/mktrans | 147 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100755 scripts/scripts/mktrans diff --git a/scripts/scripts/mktrans b/scripts/scripts/mktrans new file mode 100755 index 0000000..de65fa0 --- /dev/null +++ b/scripts/scripts/mktrans @@ -0,0 +1,147 @@ +#!/bin/bash +# B9 June 2017 + +# mktrans +# This is similar to ImageMagick's bg_removal script, but much higher +# quality. (It's also faster and simpler to use.) +# +# For a sample, run these commands: +# convert logo: logo.png +# mktrans logo.png +# display logo-transparent.png + + +# Fuzz is how far off the background color can be (in percent). +# This is important for getting good antialiasing. +defaultfuzz=20 + +usage() { + cat <] [-s|-S] [-p ,] [-v] + + -f : How loosely to match the background color (default $defaultfuzz%) + + Advanced options: + -s: Use speedy antialiasing (much faster, slightly less acurate) + -S: Supress antialiasing completely. (Useful for repeated runs) + p ,: Floodfill from pixel at x,y instead of 0,0 + -v: Verbose +EOF + +# * Side note: This creates an antialiased (blurred) alpha channel +# that is also eroded by half a pixel to avoid halos. ImageMagick's +# morphological operations don't (yet?) work at the subpixel level, +# so I'm blowing up the alpha channel to 200% before eroding. Since +# this can be slow on large images, consider using the '-s' option +# which uses a faster, lower quality antialiasing. + +# * Running this script on an image that already has transparency will +# erode the image due to the antialiasing. Using -S is a workaround, +# but is not very satisfactory. Perhaps this script should remove any +# existing transparency before manipulating the image and then add it +# back in at the end. But then again, how often are people going to +# want to do that? The only use I can think of is when using -p. + +# * Because of the previous bug, if you do use -p to fill lots of +# lagoons, you'll probably want to use -A at the same time. + +# * Finding the coordinates for -p is a pain. It'd be nice if there was +# a -P option which let the user click on a point (or multiple points) +# in the image to start the floodfill. + + exit 0 +} + +fuzz=$defaultfuzz +pixelcomma="0,0" +pixelplus="+0+0" + +while getopts f:sAShp:v name; do + case $name in + f) fuzz=$OPTARG + ;; + s) sflag=True + ;; + S|A) noantialias=True + ;; + v) vflag=True + ;; + h) usage + ;; + p) pixelcomma=$OPTARG + pixelplus=+${OPTARG%,*}+${OPTARG#*,} + pflag=True + ;; + *) usage + ;; + esac +done + +shift $((OPTIND-1)) +[[ "$#" != 0 ]] || usage + + +for filename; do + # Get color of 0,0 (top left) pixel + color=$(convert "$filename" -format "%[pixel:p{$pixelcomma}]" info:-) + if [[ "$color" == *rgba*",0)" ]]; then + color="${color%,0)},1)" # Floodfill only works with opaque colors. + fi + if [[ "$color" == "none" ]]; then + echo "Error: $filename: pixel at $pixelcomma is completely transparent. Cannot floodfill." >&2 + continue + fi + + options="" + if [ -z "$pflag" ]; then + # Add a 1 pixel border so we'll fill from the bottom and sides as well. + options+=" -bordercolor $color -border 1 " + fi + # In a new stack, make a copy of the image + options+=" ( +clone " + # [copy] floodfill with transparency ("none") starting at top-left + options+=" -fuzz $fuzz% -fill none -floodfill $pixelplus $color" + # [copy] extract just the transparency (alpha channel) + options+=" -alpha extract" + + if [ -z "$noantialias" ]; then + if [ -z "$sflag" ]; then + # [copy] blow up the alpha channel so we can do sub-pixel morphology + options+=" -geometry 200%" + # [copy] blur the alpha channel to make it antialiased + options+=" -blur 0x0.5" + # [copy] shrink the region that is opaque by half a pixel. + options+=" -morphology erode square:1" + # [copy] scale the alpha channel back to normal size. + options+=" -geometry 50%" + else # sflag: speedy antialias + # [copy] blur the alpha channel to make it antialiased + options+=" -blur 0x1" + # [copy] only antialias inside the figure (<50% opacity becomes 0%) + options+=" -level 50%,100%" + fi + fi + # [copy] end the stack. + options+=" ) " + # Compose the original image and the copy's alpha channel. + options+=" -compose CopyOpacity -composite" + if [ -z "$pflag" ]; then + # Remove the 1 pixel border we added + options+=" -shave 1" + fi + + [ "$vflag" ] && echo convert "$filename" $options "${filename%.*}-transparent.png" + + convert "$filename" $options "${filename%.*}-transparent.png" +done