Skip to content

Instantly share code, notes, and snippets.

@jerome-labidurie
Last active November 4, 2023 17:45
Show Gist options
  • Save jerome-labidurie/125ac54ed751dde37152c643736a6b6e to your computer and use it in GitHub Desktop.
Save jerome-labidurie/125ac54ed751dde37152c643736a6b6e to your computer and use it in GitHub Desktop.
Dolphin Service Menu for StableDiffusion images
#!/bin/bash
# show sd metadata
# needs imagemagick & yad
FILE=$1
id=$RANDOM
# array for all detailed information
# if belonging to a subsection (tab) key will be prefixed by its name (ControlNet_0, ADetailer ...)
declare -A details
# list of tabs name (ADetailer, ControlNet0 ...)
# use assoc array keys as a set of unique values
declare -A TABS_LIST
# tabs fields and values, indexed by TABS_LIST, holding parameters for yad
declare -A YAD_TABS_FIELDS YAD_TABS_VALUES
# list of tabs names for yad
declare -a YAD_TABS_NAME
pk="" # prekey for subsections
# get prompt, negative & details data from image
while read l
do
if [[ $l =~ ^Negative\ prompt: ]]
then
NEG=${l#Negative prompt: }
elif [[ $l =~ ^Steps: ]]
then
DET=$l
else
POS=$l
fi
done < <(identify -format "%[parameters]\n" ${FILE})
## get preKey (for subsections)
# $1 key to get for
# $2 current preKey
# return getPK_res
getPK_res=""
function getPK () {
k=$1
pk=$2
if [[ $k =~ ^ControlNet|^Lora_hashes|^TI_hashes ]]
then
npk="${k}"
elif [[ $k =~ ^ADetailer ]]
then
npk="Adetailer"
else
npk=""
fi
if [ ! -z "$npk" ]
then
TABS_LIST[$npk]=0
getPK_res="$npk-"
else
getPK_res=$pk
fi
}
# construct detailed data array
IFS=","
for elt in ${DET}
do
sep=$( expr index "$elt" : ) # : index
k=${elt:0:$(( $sep - 1 ))} # get key
k=${k## } # remove spaces at beginning
k=${k// /_} # replace spaces by _
getPK $k $pk
pk=$getPK_res # get subsection
v=${elt:$sep} # get value
details["${pk}${k}"]=${v## }
# echo "${pk}${k}:${v## }"
done
## yad cmdline for Common tab
keys=( Steps Sampler CFG_scale Seed Size Model Denoising_strength Face_restoration VAE )
YAD_FIELDS=()
YAD_VALUES=()
for k in ${keys[*]}
do
if [[ -v "details[$k]" ]]
then
# this field is present in data, add it to common tab
YAD_FIELDS+=( --field=${k//_/ } )
YAD_VALUES+=( ${details[$k]} )
fi
done
# echo ${YAD_FIELDS[*]} ${YAD_VALUES[*]}
## yad cmdline for other tabs
# many loops, bad optimization :(
for tab in ${!TABS_LIST[@]}
do
# echo tab: $tab
YAD_TABS_NAME+=( --tab=$tab )
for key in ${!details[*]}
do
if [[ $key =~ ^$tab ]]
then
# matches this tab !
text=$(echo ${details[$key]} |tr -d '"')
name=$(echo ${key#${tab}-} | tr -s '_' ' ')
YAD_TABS_FIELDS[$tab]="${YAD_TABS_FIELDS[$tab]} --field=\"$name\""
YAD_TABS_VALUES[$tab]="${YAD_TABS_VALUES[$tab]} \"$text\""
fi
done
done
# start 1st tab
yad --plug=$id --tabnum=1 --form --field="Prompt":TXT --field="Negative":TXT ${YAD_FIELDS[*]} "${POS}" "${NEG}" ${YAD_VALUES[*]} &> /tmp/${id}_1 &
# start other tabs
c=2
for tab in ${!TABS_LIST[@]}
do
# echo ${YAD_TABS_FIELDS[$tab]} ${YAD_TABS_VALUES[$tab]}
echo ${YAD_TABS_FIELDS[$tab]} ${YAD_TABS_VALUES[$tab]} | xargs yad --plug=$id --tabnum=$c --form &> /tmp/${id}_2 &
c=$(( $c + 1 ))
done
# let's go !
yad --title=$( basename ${FILE}) --width 1024 --button gtk-close --notebook --key=$id --tab="Common" ${YAD_TABS_NAME[@]}
# cleanup
rm /tmp/${id}*
[Desktop Entry]
Type=Service
ServiceTypes=KonqPopupMenu/Plugin
MimeType=image/png;application/png
Actions=showSdMetadata;
[Desktop Action showSdMetadata]
Name=Show StableDiff metadata
Name[fr]=Voir les données StableDiff
Exec=/home/jjl/sources/AI/125ac54ed751dde37152c643736a6b6e/display.sh %u
# doc https://develop.kde.org/docs/apps/dolphin/service-menus/
# cd ~/.local/share/kservices5/ServiceMenus/
# ln -s ~/sources/AI/125ac54ed751dde37152c643736a6b6e/showSdMetadata.desktop .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment