Skip to content

Instantly share code, notes, and snippets.

@hartman
Forked from LinusU/README.md
Last active August 29, 2015 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save hartman/9784684 to your computer and use it in GitHub Desktop.
Save hartman/9784684 to your computer and use it in GitHub Desktop.

Usage

Install cordova into node_modules

npm install cordova

Add icons_and_splash.js

Copy icons_and_splash.js into the .cordova/hooks/after_prepare directory.

It also needs to be executable: chmod +x .cordova/hooks/after_prepare/icons_and_splash.js

Add this to your config.xml

<icon src="res/icons/" />

Add these files to your www directory

www/res
`-- icons
    |-- android
    |   |-- icon-36-ldpi.png
    |   |-- icon-48-mdpi.png
    |   |-- icon-72-hdpi.png
    |   `-- icon-96-xhdpi.png
    `-- ios
        |-- icon-29-2x.png
        |-- icon-29.png
        |-- icon-40-2x.png
        |-- icon-40.png
        |-- icon-50-2x.png
        |-- icon-50.png
        |-- icon-57-2x.png
        |-- icon-57.png
        |-- icon-60-2x.png
        |-- icon-60.png
        |-- icon-72-2x.png
        |-- icon-72.png
        |-- icon-76-2x.png
        `-- icon-76.png

Report any error

If you get any error, please report error in comments here. I will then try to fix and update this gist accordingly. Please help us take away the pain in adding a custom icon to our applications.

#
# (Windows)
#
# What is this?
#
# It's a shell script that is using ImageMagick to create all the icon files from one source icon.
#
# If you'd like to use it on windows install ImageMagick:
# http://www.imagemagick.org/script/binary-releases.php#windows
#
# Stick the script in your 'www/res/icons' folder with your source icon 'my-hires-icon.png' then trigger it from Command Prompt.
#
mkdir android
convert my-hires-icon.png -resize 36x36 android/icon-36-ldpi.png
convert my-hires-icon.png -resize 48x48 android/icon-48-mdpi.png
convert my-hires-icon.png -resize 72x72 android/icon-72-hdpi.png
convert my-hires-icon.png -resize 96x96 android/icon-96-xhdpi.png
mkdir ios
convert my-hires-icon.png -resize 29 ios/icon-29.png
convert my-hires-icon.png -resize 40 ios/icon-40.png
convert my-hires-icon.png -resize 50 ios/icon-50.png
convert my-hires-icon.png -resize 57 ios/icon-57.png
convert my-hires-icon.png -resize 58 ios/icon-29-2x.png
convert my-hires-icon.png -resize 60 ios/icon-60.png
convert my-hires-icon.png -resize 72 ios/icon-72.png
convert my-hires-icon.png -resize 76 ios/icon-76.png
convert my-hires-icon.png -resize 80 ios/icon-40-2x.png
convert my-hires-icon.png -resize 100 ios/icon-50-2x.png
convert my-hires-icon.png -resize 114 ios/icon-57-2x.png
convert my-hires-icon.png -resize 120 ios/icon-60-2x.png
convert my-hires-icon.png -resize 144 ios/icon-72-2x.png
convert my-hires-icon.png -resize 152 ios/icon-76-2x.png
#
# (OS X, Unix and Linux)
#
# What is this?
#
# It's a shell script that is using ImageMagick to create all the icon files from one source icon.
#
# Stick the script in your 'www/res/icons' folder with your source icon 'my-hires-icon.png' then trigger it from Terminal.
#
ICON=${1:-"my-hires-icon.png"}
mkdir android
convert $ICON -resize 36x36 android/icon-36-ldpi.png
convert $ICON -resize 48x48 android/icon-48-mdpi.png
convert $ICON -resize 72x72 android/icon-72-hdpi.png
convert $ICON -resize 96x96 android/icon-96-xhdpi.png
mkdir ios
convert $ICON -resize 29 ios/icon-29.png
convert $ICON -resize 40 ios/icon-40.png
convert $ICON -resize 50 ios/icon-50.png
convert $ICON -resize 57 ios/icon-57.png
convert $ICON -resize 58 ios/icon-29-2x.png
convert $ICON -resize 60 ios/icon-60.png
convert $ICON -resize 72 ios/icon-72.png
convert $ICON -resize 76 ios/icon-76.png
convert $ICON -resize 80 ios/icon-40-2x.png
convert $ICON -resize 100 ios/icon-50-2x.png
convert $ICON -resize 114 ios/icon-57-2x.png
convert $ICON -resize 120 ios/icon-60-2x.png
convert $ICON -resize 144 ios/icon-72-2x.png
convert $ICON -resize 152 ios/icon-76-2x.png
#!/usr/bin/env node
(function() {
'use strict';
var cordova_util = require('cordova/src/util');
var projectRoot = cordova_util.isCordova(process.cwd());
var projectXml = cordova_util.projectConfig(projectRoot);
var projectPlatforms = cordova_util.listPlatforms(projectRoot);
var CordovaConfigParser,
projectConfig;
if ( typeof cordova_util.config_parser === 'undefined' ) {
CordovaConfigParser = require('cordova/src/ConfigParser');
projectConfig = new CordovaConfigParser(projectXml);
} else {
projectConfig = new cordova_util.config_parser(projectXml);
}
var fs = require ('fs');
var platformDir = {
ios: {
icon: '{$projectName}/Resources/icons',
splash: '{$projectName}/Resources/splash',
platformsDir: 'ios',
nameMap: {
// iOS >= 7 Settings icon
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPhone
'icon-29.png': 'icon-small.png',
'icon-29-2x.png': 'icon-small@2x.png',
// iOS >= 7 Spotlight search results icon (recommended)
'icon-40.png': 'icon-40.png',
'icon-40-2x.png': 'icon-40@2x.png',
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPad
'icon-50.png': 'icon-50.png',
'icon-50-2x.png': 'icon-50@2x.png',
// iOS <= 6.1 App icon (required) iPhone
'icon-57.png': 'icon.png',
'icon-57-2x.png': 'icon@2x.png',
// iOS >= 7 App icon (required) iPhone
'icon-60.png': 'icon-60.png',
'icon-60-2x.png': 'icon-60@2x.png',
// iOS <= 6.1 App icon (required) iPad
'icon-72.png': 'icon-72.png',
'icon-72-2x.png': 'icon-72@2x.png',
// iOS 7 App icon (required) iPad
'icon-76.png': 'icon-76.png',
'icon-76-2x.png': 'icon-76@2x.png',
// 'screen-iphone-landscape.png': 'Default~iphone.png',
'screen-ipad-portrait.png': 'Default-Portrait~ipad.png',
'screen-ipad-portrait-2x.png': 'Default-Portrait@2x~ipad.png',
'screen-ipad-landscape-2x.png': 'Default-Landscape@2x~ipad.png',
'screen-ipad-landscape.png': 'Default-Landscape~ipad.png',
'screen-iphone-portrait.png': 'Default~iphone.png',
'screen-iphone-portrait-2x.png': 'Default@2x~iphone.png',
'screen-iphone-portrait-568h-2x.png': 'Default-568h@2x~iphone.png'
}
},
android: {
icon:'res/drawable-{$density}',
splash:'res/drawable-{$density}',
platformsDir: 'android',
nameMap: {
'icon-36-ldpi.png': 'icon.png',
'icon-48-mdpi.png': 'icon.png',
'icon-72-hdpi.png': 'icon.png',
'icon-96-xhdpi.png': 'icon.png',
'screen-ldpi-portrait.png': 'ic_launcher.png',
'screen-mdpi-portrait.png': 'ic_launcher.png',
'screen-hdpi-portrait.png': 'ic_launcher.png',
'screen-xhdpi-portrait.png': 'ic_launcher.png'
}
},
blackberry10: {},
winphone: {
icon:'.',
splash:'.',
platformsDir: 'wp8',
nameMap: {
'icon-62.png': 'ApplicationIcon.png',
'tile-173.png': 'Background.png',
'SplashScreenImage.png': 'SplashScreenImage.jpg',
'screen-portrait-800h.jpg': 'SplashScreenImage.jpg'
}
}
};
function copyAsset (scope, node) {
var platform = node.attrib['gap:platform'];
var density = node.attrib['gap:density'];
var assetDirTmpl = platformDir[platform] && platformDir[platform][scope];
if (!assetDirTmpl) {
throw new Error('Platform and density not supported: ' + platform + ', ' + density);
}
var dict = {
projectName: projectConfig.name(),
density: density
};
var assetDir = assetDirTmpl.replace(/{\$([^}]+)}/, function (match, p1) {
return dict[p1];
});
var srcPath = node.attrib.src;
var fileName = srcPath.match(/[^\/]+$/)[0];
if (platformDir[platform] && platformDir[platform].nameMap && platformDir[platform].nameMap[fileName]) {
fileName = platformDir[platform].nameMap[fileName];
} else {
throw new Error('Unknown icon name for platform ' + platform);
}
var dstPath = 'platforms/'+platformDir[platform].platformsDir+'/'+assetDir+'/'+fileName;
if (!fs.existsSync (dstPath)) {
console.warn ('template file ' + dstPath + ' does not exist and will not be replaced' );
return;
}
console.log ('copying from '+srcPath+' to the '+dstPath);
// so, here we start to copy asset
fs.stat (srcPath, function (err, stats) {
if (err) {
throw err;
}
var r = fs.createReadStream(srcPath);
r.on ('open', function () {
r.pause();
var w = fs.createWriteStream(dstPath);
w.on ('open', function () {
r.pipe(w);
r.resume();
});
w.on ('error', function() {
throw new Error('Cannot write file');
});
});
r.on ('error', function() {
throw new Error('Cannot read file');
});
});
}
var allicons = projectConfig.doc.findall('icon');
if (allicons.length === 0 ) {
console.warn( 'No icons to install, missing icon specs in config.xml' );
} else {
console.log( 'Update all icons for project: ' + projectConfig.name() );
}
allicons.map(function (node) {
if (/\/$/.test(node.attrib.src) && node.attrib['gap:platform'] === undefined && node.attrib['gap:density'] === undefined) {
if (~projectPlatforms.indexOf('android')) {
// Android
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-36-ldpi.png', 'gap:density': 'ldpi' } });
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-48-mdpi.png', 'gap:density': 'mdpi' } });
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-72-hdpi.png', 'gap:density': 'hdpi' } });
copyAsset('icon', { attrib: { 'gap:platform': 'android', src: node.attrib.src + 'android/icon-96-xhdpi.png', 'gap:density': 'xhdpi' } });
}
if (~projectPlatforms.indexOf('ios')) {
// iOS >= 7 Settings icon
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPhone
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-29.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-29-2x.png' } });
// iOS >= 7 Spotlight search results icon (recommended)
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-40.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-40-2x.png' } });
// iOS <= 6.1 Small icon for Spotlight search results and Settings (recommended) iPad
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-50.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-50-2x.png' } });
// iOS <= 6.1 App icon (required) iPhone
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-57.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-57-2x.png' } });
// iOS >= 7 App icon (required) iPhone
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-60.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-60-2x.png' } });
// iOS <= 6.1 App icon (required) iPad
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-72.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-72-2x.png' } });
// iOS 7 App icon (required) iPad
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-76.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'ios', src: node.attrib.src + 'ios/icon-76-2x.png' } });
}
if (~projectPlatforms.indexOf('wp8')) {
copyAsset('icon', { attrib: { 'gap:platform': 'winphone', src: node.attrib.src + 'wp/icon-62.png' } });
copyAsset('icon', { attrib: { 'gap:platform': 'winphone', src: node.attrib.src + 'wp/tile-173.png' } });
}
} else {
copyAsset ('icon', node);
}
});
projectConfig.doc.findall('*').filter(function (node) {
return (node.tag === 'gap:splash');
}).map(function (node) {
copyAsset ('splash', node);
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment