Skip to content

Instantly share code, notes, and snippets.

@AncAinu
Forked from LinusU/README.md
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AncAinu/40b7d85d3c6ed77150aa to your computer and use it in GitHub Desktop.
Save AncAinu/40b7d85d3c6ed77150aa to your computer and use it in GitHub Desktop.
Forked from LinusU and fixed. Icons and Splash images for your Cordova project. (with iOS 7 support)
#
# (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
#
# (OS X)
#
# 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
sips $ICON -Z 36 -o android/icon-36-ldpi.png
sips $ICON -Z 48 -o android/icon-48-mdpi.png
sips $ICON -Z 72 -o android/icon-72-hdpi.png
sips $ICON -Z 96 -o android/icon-96-xhdpi.png
mkdir ios
sips $ICON -Z 29 -o ios/icon-29.png
sips $ICON -Z 40 -o ios/icon-40.png
sips $ICON -Z 50 -o ios/icon-50.png
sips $ICON -Z 57 -o ios/icon-57.png
sips $ICON -Z 58 -o ios/icon-29-2x.png
sips $ICON -Z 60 -o ios/icon-60.png
sips $ICON -Z 72 -o ios/icon-72.png
sips $ICON -Z 76 -o ios/icon-76.png
sips $ICON -Z 80 -o ios/icon-40-2x.png
sips $ICON -Z 100 -o ios/icon-50-2x.png
sips $ICON -Z 114 -o ios/icon-57-2x.png
sips $ICON -Z 120 -o ios/icon-60-2x.png
sips $ICON -Z 144 -o ios/icon-72-2x.png
sips $ICON -Z 152 -o ios/icon-76-2x.png
#
# (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
#!/usr/bin/env node
var cordova_util = require('cordova/src/util');
var projectRoot = cordova_util.isCordova(process.cwd());
var projectXml = cordova_util.projectConfig(projectRoot);
var ConfigParser = cordova_util.config_parser
if(undefined === ConfigParser) {
ConfigParser = require('cordova/src/ConfigParser');
}
var projectConfig = new ConfigParser(projectXml);
var projectPlatforms = cordova_util.listPlatforms(projectRoot);
projectConfig.name();
var fs = require ('fs');
var platformDir = {
ios: {
icon: "{$projectName}/Resources/icons",
splash: "{$projectName}/Resources/splash",
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}",
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: {},
wp7: {},
wp8: {}
}
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 = 'www/'+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/'+platform+'/'+assetDir+'/'+fileName;
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');
});
});
}
projectConfig.doc.findall('icon').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' } });
}
} else {
copyAsset ('icon', node);
}
});
projectConfig.doc.findall('*').filter(function (node) {
return (node.tag == 'gap:splash');
}).map(function (node) {
copyAsset ('splash', node);
});

Usage

Even if it's present in config.xml, your icons won't be set automatically in your phonegap android/ios app, unless you use the cloud service PhoneGap Builder of Adobe. For many reason you would not want to. Here is this script which allow you to solve the issue with some little efforts and without need to change generated content in your /platforms/ directory.

Install cordova into node_modules

npm install cordova

Add icons_splash.js

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

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

Add this to your config.xml

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

Be careful to don't have any <icon .../> left other than the previous line.

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.

Last tested by myself on phonegap/Cordova 3.4.0 Works with Android and iOS, can work with other systems, but you would need to complete icons_splash.js at line 77 and more.

If it doesn't update icons or splash but don't throw errors, try to remove and add the platform, it's like doing a clean command ;-)

cordova platform remove ios
cordova platform add ios

Known issues

Error: Cannot find module 'cordova/src/util'

Run npm install cordova at your project root folder.

throw new Error('Platform and density not supported: ' + platform + ', ' +

You shoud have only one tag <icon .../> in your config.xml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment