From cbb43805833a35d7556e573ad861df58da82bfb1 Mon Sep 17 00:00:00 2001 From: "C. Mangla" Date: Sun, 28 Feb 2021 19:21:28 +0000 Subject: [PATCH] Icon conversion: support GraphicsMagick in addition to ImageMagick (PR #1002) Co-authored-by: Ronan Jouchet --- README.md | 4 ++-- docs/api.md | 2 +- icon-scripts/convertToIcns | 6 ++++-- icon-scripts/convertToIco | 9 +++++++-- icon-scripts/convertToIconset | 13 ++++++++----- icon-scripts/convertToPng | 27 +++++++++++++++++++++++---- src/helpers/helpers.ts | 4 ++-- 7 files changed, 47 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index fcbd4f0..b592b72 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,8 @@ through the numerous open tabs when I was using [Facebook Messenger](https://mes - macOS 10.9+ / Windows / Linux - [Node.js](https://nodejs.org/) `>= 10` and npm `>= 6` - Optional dependencies: - - [ImageMagick](http://www.imagemagick.org/) to convert icons. - Make sure `convert` and `identify` are in your system `$PATH`. + - [ImageMagick](http://www.imagemagick.org/) or [GraphicsMagick](http://www.graphicsmagick.org/) to convert icons. + Make sure `convert` and `identify` or `gm` are in your system `$PATH`. - [Wine](https://www.winehq.org/) to package Windows apps under non-Windows platforms. Make sure `wine` is in your system `$PATH`. diff --git a/docs/api.md b/docs/api.md index 0e804f4..5f72df6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -218,7 +218,7 @@ The icon parameter should be a path to a `.png` file. The icon parameter can either be a `.icns` or a `.png` file if the [optional dependencies](../README.md#optional-dependencies) are installed. -If you have the optional dependencies `iconutil`, Imagemagick `convert`, and Imagemagick `identify` in your `PATH`, Nativefier will automatically convert the `.png` to a `.icns` for you. +If your `PATH` has our image-conversion dependencies (`iconutil`, and either ImageMagick `convert` + `identify`, or GraphicsMagick `gm`), Nativefier will automatically convert the `.png` to a `.icns` for you. On MacOS 10.14+, if you have set a global shortcut that includes a Media key, the user will need to be prompted for permissions to enable these keys in System Preferences > Security & Privacy > Accessibility. diff --git a/icon-scripts/convertToIcns b/icon-scripts/convertToIcns index ad4698b..dfd3671 100755 --- a/icon-scripts/convertToIcns +++ b/icon-scripts/convertToIcns @@ -13,13 +13,15 @@ set -e HAVE_IMAGEMAGICK= HAVE_ICONUTIL= HAVE_SIPS= +HAVE_GRAPHICSMAGICK= type convert &>/dev/null && HAVE_IMAGEMAGICK=true type iconutil &>/dev/null && HAVE_ICONUTIL=true type sips &>/dev/null && HAVE_SIPS=true +type gm &>/dev/null && gm version | grep GraphicsMagick &>/dev/null && HAVE_GRAPHICSMAGICK=true [[ -z "$HAVE_ICONUTIL" ]] && { echo >&2 "Cannot find required iconutil executable"; exit 1; } -[[ -z "$HAVE_IMAGEMAGICK" && -z "$HAVE_SIPS" ]] && { echo >&2 "Cannot find required image converter, please install sips or imagemagick"; exit 1; } +[[ -z "$HAVE_IMAGEMAGICK" && -z "$HAVE_SIPS" && -z "$HAVE_GRAPHICSMAGICK" ]] && { echo >&2 "Cannot find required image converter, please install sips, imagemagick or graphicsmagick"; exit 1; } # Parameters SOURCE="$1" @@ -36,7 +38,7 @@ if [ -z "${DEST}" ]; then exit 1 fi -TEMP_DIR="$(mktemp -d)" +TEMP_DIR="$(mktemp -d -t nativefier_icons)" ICONSET="${TEMP_DIR}/converted.iconset" function cleanUp() { diff --git a/icon-scripts/convertToIco b/icon-scripts/convertToIco index 25a59e8..737a2e1 100755 --- a/icon-scripts/convertToIco +++ b/icon-scripts/convertToIco @@ -8,7 +8,12 @@ set -e -type convert >/dev/null 2>&1 || { echo >&2 "Cannot find required ImageMagick Convert executable"; exit 1; } +CONVERT= + +type gm &>/dev/null && gm version | grep GraphicsMagick &>/dev/null && CONVERT="gm convert" +type convert &>/dev/null && CONVERT="convert" + +[[ -z "$CONVERT" ]] && { echo >&2 "Cannot find required ImageMagick Convert or GraphicsMagick executable"; exit 1; } SOURCE=$1 DEST=$2 @@ -31,4 +36,4 @@ if [ "${EXT}" == "ico" ]; then exit 0 fi -convert "${SOURCE}" -resize 256x256 "${DEST}" +$CONVERT "${SOURCE}" -resize 256x256 "${DEST}" diff --git a/icon-scripts/convertToIconset b/icon-scripts/convertToIconset index 1492be5..3ab3d18 100755 --- a/icon-scripts/convertToIconset +++ b/icon-scripts/convertToIconset @@ -17,8 +17,8 @@ make_iconset_imagemagick() { mkdir "$iconset" for size in {16,32,64,128,256,512}; do - convert "${file}" -define png:big-depth=16 -define png:color-type=6 -sample "${size}x${size}" "${iconset}/icon_${size}x${size}.png" - convert "${file}" -define png:big-depth=16 -define png:color-type=6 -sample "$((size * 2))x$((size * 2))" "${iconset}/icon_${size}x${size}@2x.png" + $CONVERT "${file}" -define png:big-depth=16 -define png:color-type=6 -sample "${size}x${size}" "${iconset}/icon_${size}x${size}.png" + $CONVERT "${file}" -define png:big-depth=16 -define png:color-type=6 -sample "$((size * 2))x$((size * 2))" "${iconset}/icon_${size}x${size}@2x.png" done } @@ -50,15 +50,18 @@ fi HAVE_IMAGEMAGICK= HAVE_SIPS= +HAVE_GRAPHICSMAGICK= +CONVERT= -type convert &>/dev/null && HAVE_IMAGEMAGICK=true +type gm &>/dev/null && gm version | grep GraphicsMagick &>/dev/null && HAVE_GRAPHICSMAGICK=true && CONVERT="gm convert" +type convert &>/dev/null && HAVE_IMAGEMAGICK=true && CONVERT="convert" type sips &>/dev/null && HAVE_SIPS=true -if [[ ! -z "$HAVE_IMAGEMAGICK" ]]; then +if [[ -n "$HAVE_IMAGEMAGICK" || -n "$HAVE_GRAPHICSMAGICK" ]]; then PNG_PATH="$(mktemp -d)/icon.png" "${BASH_SOURCE%/*}/convertToPng" "${SOURCE}" "${PNG_PATH}" make_iconset_imagemagick "${PNG_PATH}" "${DEST}" -elif [[ ! -z "$HAVE_SIPS" ]]; then +elif [[ -n "$HAVE_SIPS" ]]; then make_iconset_sips "${SOURCE}" "${DEST}" else echo >&2 "Cannot find convert or sips executables"; exit 1; diff --git a/icon-scripts/convertToPng b/icon-scripts/convertToPng index ff77284..cd6ce8c 100755 --- a/icon-scripts/convertToPng +++ b/icon-scripts/convertToPng @@ -8,8 +8,27 @@ set -e -type convert >/dev/null 2>&1 || { echo >&2 "Cannot find required ImageMagick 'convert' executable, please install it and make sure it is in your PATH"; exit 1; } -type identify >/dev/null 2>&1 || { echo >&2 "Cannot find required ImageMagick 'identify' executable, please install it and make sure it is in your PATH"; exit 1; } +HAVE_IMAGEMAGICK= +HAVE_GRAPHICSMAGICK= + +type convert &>/dev/null && type identify &>/dev/null && HAVE_IMAGEMAGICK=true +type gm &>/dev/null && gm version | grep GraphicsMagick &>/dev/null && HAVE_GRAPHICSMAGICK=true + +if [[ -z "$HAVE_IMAGEMAGICK" && -z "$HAVE_GRAPHICSMAGICK" ]]; then + type convert >/dev/null 2>&1 || echo >&2 "Cannot find required ImageMagick 'convert' executable" + type identify >/dev/null 2>&1 || echo >&2 "Cannot find required ImageMagick 'identify' executable" + type gm &>/dev/null && gm version | grep GraphicsMagick &>/dev/null && echo >&2 "Cannot find GraphicsMagick" + echo >&2 "ImageMagic or GraphicsMagic is required, please ensure they are in your PATH" + exit 1 +fi + +CONVERT="convert" +IDENTIFY="identify" +if [[ -z "$HAVE_IMAGEMAGICK" ]]; then + # we must have GraphicsMagick then + CONVERT="gm convert" + IDENTIFY="gm identify" +fi # Parameters SOURCE="$1" @@ -41,9 +60,9 @@ mkdir -p "${TEMP_DIR}" # check if .ico is a sequence # pipe into cat so no exit code is given for grep if no matches are found -IS_ICO_SET="$(identify "${SOURCE}" | grep -e "\w\.ico\[0" | cat )" +IS_ICO_SET="$($IDENTIFY "${SOURCE}" | grep -e "\w\.ico\[0" | cat )" -convert "${SOURCE}" "${TEMP_DIR}/${BASE}.png" +$CONVERT "${SOURCE}" "${TEMP_DIR}/${BASE}.png" if [ "${IS_ICO_SET}" ]; then # extract the largest(?) image from the set cp "${TEMP_DIR}/${BASE}-0.png" "${DEST}" diff --git a/src/helpers/helpers.ts b/src/helpers/helpers.ts index 15178e7..aabab81 100644 --- a/src/helpers/helpers.ts +++ b/src/helpers/helpers.ts @@ -68,8 +68,8 @@ export async function downloadFile(fileUrl: string): Promise { } export function getAllowedIconFormats(platform: string): string[] { - const hasIdentify = hasbin.sync('identify'); - const hasConvert = hasbin.sync('convert'); + const hasIdentify = hasbin.sync('identify') || hasbin.sync('gm'); + const hasConvert = hasbin.sync('convert') || hasbin.sync('gm'); const hasIconUtil = hasbin.sync('iconutil'); const pngToIcns = hasConvert && hasIconUtil;