diff --git a/stpkg b/stpkg index 5bdfabaf80616ac999550e16212c97047c023591..39a3437c11e41b8023d7872a3b7173d6f1cc2a70 100755 --- a/stpkg +++ b/stpkg @@ -8,13 +8,17 @@ # Fix add/del # Test other output formats # Thumbnails: https://github.com/matrix-org/synapse/issues/13039 (manually upload small version of the sticker (32x32?) and uses this as thumbnail_url) +# Fix choice between apng or gif shopt -s nocasematch # Case insensitive STPKG_CONF_FILE=~/.config/stpkg.sh BASE_DIR="$PWD" -declare -A animatedFiletype=(gif apng) +declare -A animatedFiletype=( + ["image/gif"]="à¶ž" + ["image/apng"]="à¶ž" +) # Detect install if [ "x$1" = "x-install" ]; then @@ -64,7 +68,7 @@ require() { done } require \ - md5sum mktemp column uuidgen convert montage identify python3 curl \ + md5sum mktemp column uuidgen convert montage identify python3 curl ffmpeg \ sed tr git sponge ls find jq chmod cat expr iconv bc __grep=`which egrep` if [ -z $__grep ]; then @@ -177,7 +181,9 @@ __get_dest_dimensions() { local INIT_WIDTH=$1 local INIT_HEIGHT=$2 local MAX_WIDTH=$3 - local MAX_HEIGHT=$3 + local MAX_HEIGHT=$4 + local DEST_SEP="$5" + local DEFAULT_DIST="$6" local WIDTH_RATIO="$(echo "scale=10; $INIT_WIDTH/$STPKG_MAX_WIDTH" | bc)" local HEIGHT_RATIO="$(echo "scale=10; $INIT_HEIGHT/$STPKG_MAX_HEIGHT" | bc)" @@ -185,24 +191,33 @@ __get_dest_dimensions() { if [ $(echo "$HEIGHT_RATIO >= $WIDTH_RATIO" | bc) = "1" ]; then if [ $(echo "$HEIGHT_RATIO > 1" | bc) = "1" ]; then local DEST_HEIGHT=$STPKG_MAX_HEIGHT - local DEST_WIDTH="" + local DEST_WIDTH="$DEFAULT_DIST" else local DEST_HEIGHT=$INIT_HEIGHT local DEST_WIDTH=$INIT_WIDTH fi elif [ $(echo "$WIDTH_RATIO > 1" | bc) = "1" ]; then - local DEST_HEIGHT="" + local DEST_HEIGHT="$DEFAULT_DIST" local DEST_WIDTH=$STPKG_MAX_WIDTH else local DEST_HEIGHT=$INIT_HEIGHT local DEST_WIDTH=$INIT_WIDTH fi - echo "${DEST_WIDTH}x${DEST_HEIGHT}" + echo "${DEST_WIDTH}${DEST_SEP}${DEST_HEIGHT}" } -file_get_type() { xdg-mime query filetype "$1"; } +is_apng() { identify apng:"$1" | grep -Fq "$1[1]" && echo "1" || echo "0"; } +file_get_type(){ + ret="`xdg-mime query filetype "$1"`" + if [[ "x$ret" == "ximage/png" ]]; then + if [[ "x`is_apng "$1"`" == "x1" ]]; then + ret="image/apng" + fi + fi + echo -n "$ret" +} file_get_ext() { xdg-mime query filetype "$1" | sed 's+^.*/++'; } file_get_ext_from_type() { echo "$1" | sed 's+^.*/++'; } file_get_name() { echo -n "$1" | sed 's/.[^.]*$//'; } @@ -590,12 +605,12 @@ process_sticker_file() { local NAME=$(file_get_name "$FILE") local TEMP=`mktemp --suffix=.stpkg` - if [ "x$TYPE" != "xgif" ] && [ "x$TYPE" != "xpng" ]; then - local DSTTYPE="png" + if [[ ! ${animatedFiletype[$INIT_TYPE]} ]]; then + local DEST_TYPE="png" else - local DSTTYPE="$TYPE" + local DEST_TYPE="$INIT_TYPE" fi - local DEST="$DEST_FOLDER/$NAME.$DSTTYPE" + local DEST="$DEST_FOLDER/$NAME.$DEST_TYPE" if [ "x${STPKG_NOCONVERT_FILE}" = "xyes" ]; then # @@ -605,27 +620,40 @@ process_sticker_file() { cp ${FILE} ${TEMP} else - if [[ ${animatedFiletype[$INIT_EXT]} ]]; then + if [[ ${animatedFiletype[$INIT_TYPE]} ]]; then # # Convert animated image # - local DEST_TYPE=$STPKG_ANIMATED_TARGET_FILETYPE - local DEST_EXT=$(file_get_ext_from_type "$DEST_TYPE") + if [[ "$INIT_TYPE" == "image/apng" ]] && [[ "$STPKG_ALLOW_APNG" == "yes" ]]; then + # FIXME: properly crop apngs - local backgroundColor="`convert "${FILE}[0]" -format "%[pixel:u.p{0,0}]" info:`" - convert "${FILE}" -dispose previous -background "${backgroundColor}" -trim -layers TrimBounds -coalesce "$DEST_EXT:${TEMP}" 1>&2 \ - || die "$NAME failed trimming the sticker" + local DEST_TYPE="image/apng" - # Get sizes - local INIT_WIDTH=$(file_get_width "${TEMP}") - local INIT_HEIGHT=$(file_get_height "${TEMP}") - local DEST_DIMENSIONS=$(__get_dest_dimensions $INIT_WIDTH $INIT_HEIGHT $STPKG_MAX_WIDTH $STPKG_MAX_HEIGHT) + # Get sizes + local INIT_WIDTH=$(file_get_width "${FILE}") + local INIT_HEIGHT=$(file_get_height "${FILE}") + local DEST_DIMENSIONS=$(__get_dest_dimensions $INIT_WIDTH $INIT_HEIGHT $STPKG_MAX_WIDTH $STPKG_MAX_HEIGHT ":" "-1") - convert "${TEMP}" -coalesce -dispose previous -resize ${DEST_DIMENSIONS} "$DEST_EXT:${TEMP}" 1>&2 \ - || die "$NAME failed resizing the sticker" + ffmpeg -y -loglevel warning -f apng -i "${FILE}" -plays 0 -vf scale=${DEST_DIMENSIONS} -f apng "${TEMP}" >/dev/null + else + local DEST_TYPE=$STPKG_ANIMATED_TARGET_FILETYPE + local DEST_EXT=$(file_get_ext_from_type "$DEST_TYPE") + + local backgroundColor="`convert "${FILE}[0]" -format "%[pixel:u.p{0,0}]" info:`" + convert "${INIT_EXT}:${FILE}" -dispose previous -background "${backgroundColor}" -trim -layers TrimBounds -coalesce "$DEST_EXT:${TEMP}" 1>&2 \ + || die "$NAME failed trimming the sticker" + + # Get sizes + local INIT_WIDTH=$(file_get_width "${TEMP}") + local INIT_HEIGHT=$(file_get_height "${TEMP}") + local DEST_DIMENSIONS=$(__get_dest_dimensions $INIT_WIDTH $INIT_HEIGHT $STPKG_MAX_WIDTH $STPKG_MAX_HEIGHT "x" "") - # Can't optimize the gif because discord doesn't know how to display them properly (for bridged channels) - #convert "${TEMP}" -coalesce -layers Optimize "$DEST_EXT:${TEMP}" 1>&2 \ + convert "${TEMP}" -coalesce -dispose previous -resize ${DEST_DIMENSIONS} "$DEST_EXT:${TEMP}" 1>&2 \ + || die "$NAME failed resizing the sticker" + + # Can't optimize the gif because discord doesn't know how to display them properly (for bridged channels) + #convert "${TEMP}" -coalesce -layers Optimize "$DEST_EXT:${TEMP}" 1>&2 \ + fi else # @@ -639,7 +667,7 @@ process_sticker_file() { # Get sizes local INIT_WIDTH=$(file_get_width "$TEMP") local INIT_HEIGHT=$(file_get_height "$TEMP") - local DEST_DIMENSIONS=$(__get_dest_dimensions $INIT_WIDTH $INIT_HEIGHT $STPKG_MAX_WIDTH $STPKG_MAX_HEIGHT) + local DEST_DIMENSIONS=$(__get_dest_dimensions $INIT_WIDTH $INIT_HEIGHT $STPKG_MAX_WIDTH $STPKG_MAX_HEIGHT "x" "") convert "$TEMP" -bordercolor none -border 1 -background none -gravity center -trim +repage -resize ${DEST_DIMENSIONS} "${DEST_EXT}:${TEMP}" 1>&2 \ || die "$NAME failed converting the sticker"