Add conversion of multiple ico to single ico

This commit is contained in:
Jia Hao 2016-03-09 14:45:08 +08:00
parent 38a15baac2
commit a5e3c5c2f8
3 changed files with 142 additions and 2 deletions

71
bin/singleIco Executable file
View File

@ -0,0 +1,71 @@
#!/bin/sh
# USAGE
# ./extractIco <input ico> <outp ico>
# Make sure the output extension is '.ico'!
# Example
# ./extractIco.sh ~/SOME_MULTIPLE_ICO.png ~/Desktop/SINGLE.ico
# Exec Paths
IMAGEMAGICK_CONVERT=$(which convert)
IMAGEMAGICK_IDENTIFY=$(which identify)
if [ ! -x "${IMAGEMAGICK_CONVERT}" ]; then
echo "Cannot find required ImageMagick Convert executable" >&2
exit 1;
fi
if [ ! -x "${IMAGEMAGICK_IDENTIFY}" ]; then
echo "Cannot find required ImageMagick Identify executable" >&2
exit 1;
fi
# Parameters
SOURCE=$1
DEST=$2
# Check source and destination arguments
if [ -z "${SOURCE}" ]; then
echo "No source image specified" >&2
exit 1
fi
if [ -z "${DEST}" ]; then
echo "No destination specified" >&2
exit 1
fi
# check if source exists
if [ ! -f "${SOURCE}" ]; then
echo "Source file not found" >&2
exit 1
fi
# File Infrastructure
NAME=$(basename "${SOURCE}")
EXT="${NAME##*.}"
BASE="${NAME%.*}"
TEMP_DIR="${BASE}.iconset"
if [ "${EXT}" != "ico" ]; then
echo "Source file is not a .ico" >&2
exit 1
fi
# check if .ico is a sequence
IS_ICO_SET="$(identify ${SOURCE} | grep -e "\w\.ico\[0")"
if [ "${IS_ICO_SET}" ]; then
mkdir "${TEMP_DIR}"
# extract the largest(?) image from the set
convert "${SOURCE}" "${TEMP_DIR}/${BASE}.png"
convert "${TEMP_DIR}/${BASE}-0.png" "${DEST}"
# Clean up the temp dir
rm -rf "${TEMP_DIR}"
else
cp "${SOURCE}" "${DEST}"
fi

View File

@ -1,6 +1,7 @@
import path from 'path';
import helpers from './../helpers/helpers';
import pngToIcns from './../helpers/pngToIcns';
import singleIco from './../helpers/singleIco';
const isOSX = helpers.isOSX;
/**
@ -27,11 +28,30 @@ function iconBuild(options, callback) {
return;
}
if (options.platform !== 'darwin') {
if (options.platform === 'win32') {
if (!iconIsIco(options.icon)) {
console.warn('Icon should be an .ico to package for Windows');
returnCallback();
return;
}
singleIco(options.icon)
.then(outPath => {
options.icon = outPath;
returnCallback();
})
.catch(error => {
console.warn('Skipping icon conversion from `.png` to `.icns`: ', error);
returnCallback();
});
return;
}
if (options.platform === 'linux') {
if (iconIsPng(options.icon)) {
returnCallback();
} else {
console.warn('Icon should be a png for Linux and Windows apps');
console.warn('Icon should be a .png to package for Linux');
returnCallback();
}
return;
@ -57,6 +77,10 @@ function iconBuild(options, callback) {
});
}
function iconIsIco(iconPath) {
return path.extname(iconPath) === '.ico';
}
function iconIsPng(iconPath) {
return path.extname(iconPath) === '.png';
}

45
src/helpers/singleIco.js Normal file
View File

@ -0,0 +1,45 @@
import shell from 'shelljs';
import path from 'path';
import tmp from 'tmp';
tmp.setGracefulCleanup();
const EXTRACT_ICO_PATH = path.join(__dirname, '../..', 'bin/singleIco');
/**
*
* @param {string} icoSrc input .ico
* @param {string} dest has to be a .ico path
*/
function singleIco(icoSrc, dest) {
return new Promise((resolve, reject) => {
shell.exec(`${EXTRACT_ICO_PATH} ${icoSrc} ${dest}`, {silent: true}, (exitCode, stdOut, stdError) => {
if (stdOut.includes('icon.iconset:error') || exitCode) {
if (exitCode) {
reject({
stdOut: stdOut,
stdError: stdError
});
return;
}
reject(stdOut);
return;
}
resolve(dest);
});
});
}
/**
* Converts the ico to a temporary directory which will be cleaned up on process exit
* @param {string} icoSrc path to a .ico file
*/
function singleIcoTmp(icoSrc) {
const tempIconDirObj = tmp.dirSync({unsafeCleanup: true});
const tempIconDirPath = tempIconDirObj.name;
return singleIco(icoSrc, `${tempIconDirPath}/icon.ico`);
}
export default singleIcoTmp;