Skip to content

Instantly share code, notes, and snippets.

@LinusU
Forked from apla/icons_and_splash.js
Last active July 17, 2021 08:06
Show Gist options
  • Save LinusU/7515016 to your computer and use it in GitHub Desktop.
Save LinusU/7515016 to your computer and use it in GitHub Desktop.
Icons and Splash images for your Cordova project. (with iOS 7 support)

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
var cordova_util = require('cordova/src/util');
var projectRoot = cordova_util.isCordova(process.cwd());
var projectXml = cordova_util.projectConfig(projectRoot);
var projectConfig = new cordova_util.config_parser(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);
});
@MGalv
Copy link

MGalv commented Sep 2, 2014

For cordoba-lib version ~> 0.21.4, you should change this line:

CordovaConfigParser = require('cordova-lib/src/cordova/configparser');

for this one:

CordovaConfigParser = require('cordova-lib').configparser;

@3dcinetv
Copy link

It´s been 2 days now, please help me solve this error, please:
On my cmd I type:

D:\VB4>phonegap build android

Then it returns:
[phonegap] executing 'cordova build android'...
D:\VB4\res\icons\ is a directory (not copied)

Running command: "C:\Program Files\nodejs\node.exe" D:\VB4\hooks\after_prepare\i
cons_and_splash.js D:\VB4

module.js:338
throw err;
^

Error: Cannot find module 'cordova/src/util'
at Function.Module._resolveFilename (module.js:336:15)
at Function.Module._load (module.js:286:25)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (D:\VB4\hooks\after_prepare\icons_and_splash.js:3:20)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)

Error: Hook failed with error code 1: D:\VB4\hooks\after_prepare\icons_and_splas
h.js

@ekorslin
Copy link

Hi everyone,
I'm getting the following after attempting to run cordova emulate ios with my cordova app. Any suggestions for a fix?

/Users/ekorslin/Desktop/cordovaReactProject/hooks/after_prepare/icons_and_splash.js:127
        throw new Error('Cannot write file');
        ^

Error: Cannot write file
    at WriteStream.<anonymous> (/Users/ekorslin/Desktop/cordovaReactProject/hooks/after_prepare/icons_and_splash.js:127:15)

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