Skip to content

Instantly share code, notes, and snippets.

@dalezak
Last active September 11, 2023 09:51
Show Gist options
  • Star 99 You must be signed in to star a gist
  • Fork 29 You must be signed in to fork a gist
  • Save dalezak/a6b1de39091f4ace220695d72717ac71 to your computer and use it in GitHub Desktop.
Save dalezak/a6b1de39091f4ace220695d72717ac71 to your computer and use it in GitHub Desktop.
Ionic Capacitor Resources Generator
  1. Run npm install cordova-res --save-dev
  2. Create 1024x1024px icon at resources/icon.png
  3. Create 2732x2732px splash at resources/splash.png
  4. Add "resources": "cordova-res ios && cordova-res android && node scripts/resources.js" to scripts in package.json
  5. Copy resources.js file to scripts/resources.js
  6. Run sudo chmod -R 777 scripts/resources.js
  7. Run npm run resources
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"resources": "cordova-res ios && cordova-res android && node scripts/resources.js"
}
const fs = require('fs');
const SOURCE_IOS_ICON = 'resources/ios/icon/';
const SOURCE_IOS_SPLASH = 'resources/ios/splash/';
const TARGET_IOS_ICON = 'ios/App/App/Assets.xcassets/AppIcon.appiconset/';
const TARGET_IOS_SPLASH = 'ios/App/App/Assets.xcassets/Splash.imageset/';
const SOURCE_ANDROID_ICON = 'resources/android/icon/';
const SOURCE_ANDROID_SPLASH = 'resources/android/splash/';
const TARGET_ANDROID_ICON = 'android/app/src/main/res/';
const TARGET_ANDROID_SPLASH = 'android/app/src/main/res/';
const IOS_ICONS = [
{ source: 'icon-20.png', target: 'AppIcon-20x20@1x.png' },
{ source: 'icon-20@2x.png', target: 'AppIcon-20x20@2x.png' },
{ source: 'icon-20@2x.png', target: 'AppIcon-20x20@2x-1.png' },
{ source: 'icon-20@3x.png', target: 'AppIcon-20x20@3x.png' },
{ source: 'icon-29.png', target: 'AppIcon-29x29@1x.png' },
{ source: 'icon-29@2x.png', target: 'AppIcon-29x29@2x.png' },
{ source: 'icon-29@2x.png', target: 'AppIcon-29x29@2x-1.png' },
{ source: 'icon-29@3x.png', target: 'AppIcon-29x29@3x.png' },
{ source: 'icon-40.png', target: 'AppIcon-40x40@1x.png' },
{ source: 'icon-40@2x.png', target: 'AppIcon-40x40@2x.png' },
{ source: 'icon-40@2x.png', target: 'AppIcon-40x40@2x-1.png' },
{ source: 'icon-40@3x.png', target: 'AppIcon-40x40@3x.png' },
{ source: 'icon-60@2x.png', target: 'AppIcon-60x60@2x.png' },
{ source: 'icon-60@3x.png', target: 'AppIcon-60x60@3x.png' },
{ source: 'icon-76.png', target: 'AppIcon-76x76@1x.png' },
{ source: 'icon-76@2x.png', target: 'AppIcon-76x76@2x.png' },
{ source: 'icon-83.5@2x.png', target: 'AppIcon-83.5x83.5@2x.png' },
{ source: 'icon-1024.png', target: 'AppIcon-512@2x.png' }
];
const IOS_SPLASHES = [
{ source: 'Default-Portrait@~ipadpro.png', target: 'splash-2732x2732.png' },
{ source: 'Default-Portrait@~ipadpro.png', target: 'splash-2732x2732-1.png' },
{ source: 'Default-Portrait@~ipadpro.png', target: 'splash-2732x2732-2.png' }
];
const ANDROID_ICONS = [
{ source: 'drawable-ldpi-icon.png', target: 'drawable-hdpi-icon.png' },
{ source: 'drawable-mdpi-icon.png', target: 'mipmap-mdpi/ic_launcher.png' },
{ source: 'drawable-mdpi-icon.png', target: 'mipmap-mdpi/ic_launcher_round.png' },
{ source: 'drawable-mdpi-icon.png', target: 'mipmap-mdpi/ic_launcher_foreground.png' },
{ source: 'drawable-hdpi-icon.png', target: 'mipmap-hdpi/ic_launcher.png' },
{ source: 'drawable-hdpi-icon.png', target: 'mipmap-hdpi/ic_launcher_round.png' },
{ source: 'drawable-hdpi-icon.png', target: 'mipmap-hdpi/ic_launcher_foreground.png' },
{ source: 'drawable-xhdpi-icon.png', target: 'mipmap-xhdpi/ic_launcher.png' },
{ source: 'drawable-xhdpi-icon.png', target: 'mipmap-xhdpi/ic_launcher_round.png' },
{ source: 'drawable-xhdpi-icon.png', target: 'mipmap-xhdpi/ic_launcher_foreground.png' },
{ source: 'drawable-xxhdpi-icon.png', target: 'mipmap-xxhdpi/ic_launcher.png' },
{ source: 'drawable-xxhdpi-icon.png', target: 'mipmap-xxhdpi/ic_launcher_round.png' },
{ source: 'drawable-xxhdpi-icon.png', target: 'mipmap-xxhdpi/ic_launcher_foreground.png' },
{ source: 'drawable-xxxhdpi-icon.png', target: 'mipmap-xxxhdpi/ic_launcher.png' },
{ source: 'drawable-xxxhdpi-icon.png', target: 'mipmap-xxxhdpi/ic_launcher_round.png' },
{ source: 'drawable-xxxhdpi-icon.png', target: 'mipmap-xxxhdpi/ic_launcher_foreground.png' }
];
const ANDROID_SPLASHES = [
{ source: 'drawable-land-mdpi-screen.png', target: 'drawable/splash.png' },
{ source: 'drawable-land-mdpi-screen.png', target: 'drawable-land-mdpi/splash.png' },
{ source: 'drawable-land-hdpi-screen.png', target: 'drawable-land-hdpi/splash.png' },
{ source: 'drawable-land-xhdpi-screen.png', target: 'drawable-land-xhdpi/splash.png' },
{ source: 'drawable-land-xxhdpi-screen.png', target: 'drawable-land-xxhdpi/splash.png' },
{ source: 'drawable-land-xxxhdpi-screen.png', target: 'drawable-land-xxxhdpi/splash.png' },
{ source: 'drawable-port-mdpi-screen.png', target: 'drawable-port-mdpi/splash.png' },
{ source: 'drawable-port-hdpi-screen.png', target: 'drawable-port-hdpi/splash.png' },
{ source: 'drawable-port-xhdpi-screen.png', target: 'drawable-port-xhdpi/splash.png' },
{ source: 'drawable-port-xxhdpi-screen.png', target: 'drawable-port-xxhdpi/splash.png' },
{ source: 'drawable-port-xxxhdpi-screen.png', target: 'drawable-port-xxxhdpi/splash.png' }
];
function copyImages(sourcePath, targetPath, images) {
for (const icon of images) {
let source = sourcePath + icon.source;
let target = targetPath + icon.target;
fs.copyFile(source, target, err => {
if (err) throw err;
console.log(`${source} >> ${target}`);
});
}
}
copyImages(SOURCE_IOS_ICON, TARGET_IOS_ICON, IOS_ICONS);
copyImages(SOURCE_IOS_SPLASH, TARGET_IOS_SPLASH, IOS_SPLASHES);
copyImages(SOURCE_ANDROID_ICON, TARGET_ANDROID_ICON, ANDROID_ICONS);
copyImages(SOURCE_ANDROID_SPLASH, TARGET_ANDROID_SPLASH, ANDROID_SPLASHES);
@nprail
Copy link

nprail commented Oct 20, 2019

Thanks for this script! It makes things a lot easier.

It only mostly works, though. Because certain icon/splash keys are the same (e.g. icon-20@2x.png), JavaScript drops the duplicate keys. I swapped the keys and values since all of the values are unique and that worked. Maybe a better solution would be an array with a source and target filename?

@dalezak
Copy link
Author

dalezak commented Oct 20, 2019

Ah yes, good catch! I’ll make the change to the gist 👍

@rrlevy
Copy link

rrlevy commented Oct 23, 2019

@dalezak, I've created a fork of this gist and changed the icon/splash list from a object to arrays, in order to fix the issue mentioned by @nprail that would skip duplicated icons.

I've also changed the list of icons on resources.js a bit, to be consistent with the icons the current capacitor version is generating.
I've followed the list provided at the ios template of capacitor git repo and the Android icons actually generated by capacitor when using npx cap add
I haven't removed the previously listed icons, but I just commented them for your review

@dalezak
Copy link
Author

dalezak commented Oct 24, 2019

Hey @rrlevy, thanks for sharing this!

I've been swamped with a new job plus a new baby, so appreciate the fork. I've copied over the suggestions @nprail 👍

@Rebbaca
Copy link

Rebbaca commented Dec 26, 2019

@dalezak I love it, thank you so much! BTW, I'm also using Vue + Bootstrap + Capacitor! Awesome stuff!

Excuse me. I'm also using vue + capacitor, but there's an error and I'm leaving a comment. Is it right to create the resources and scripts folders at the top? If I follow all the flow and run 'npm run resources', the system generates an error called 'No config.xml file in directory. Skipping config.' followed by 'Error with source file resources/icon.png: Error'.

@mohsin363
Copy link

mohsin363 commented Feb 1, 2020

@dalezek how to get icons for PWA?

@dalezak
Copy link
Author

dalezak commented Feb 1, 2020

@mohsin363 this isn't necessary for the PWA since a web version has no splash screen or app icon.

That being said, it might be possible to modify the script to also generate favicon.ico for the browser tab.

@madmacc
Copy link

madmacc commented Feb 8, 2020

@dalezak @rrlevy
That works pretty well. Nice work. With the splash images generated using cordova-res I noticed these are just cropped not resized.
This makes for some pretty awful looking splash screens at the lower resolutions.
Is there any way to to resize the image like image gorilla does?
https://apetools.webprofusion.com/#/tools/imagegorilla

@vkyeswa
Copy link

vkyeswa commented Feb 28, 2020

@madmacc you might have to adjust your splash image to the dimensions (2732x2732px) mentioned in step 3 of the README.md

@damienromito
Copy link

awesome, thank you @dalezak

@Gabriel1590
Copy link

it is not working for me i have windows and i cant run the sudo chmod and when i run the npm this err appear
errno: -4058, code: 'ENOENT', syscall: 'copyfile', path: 'C:\\Users\\pc\\Documents\\Negocio\\Bolution\\Code\\bolution\\resources\\ios\\icon\\icon-20@2x.png', dest: 'C:\\Users\\pc\\Documents\\Negocio\\Bolution\\Code\\bolution\\ios\\App\\App\\Assets.xcassets\\AppIcon.appiconset\\AppIcon-20x20@2x.png' } npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! bolution@0.0.1 resources:cordova-res ios && cordova-res android && node scripts/resources.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the bolution@0.0.1 resources script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\pc\AppData\Roaming\npm-cache_logs\2020-07-21T00_30_34_827Z-debug.log`

@w-mazed
Copy link

w-mazed commented Jul 21, 2020

@nprail
Copy link

nprail commented Jul 21, 2020

@Gabriel1590 cordova-res now supports Capacitor directly. https://github.com/ionic-team/cordova-res#capacitor

@golontico
Copy link

@Gabriel1590 cordova-res now supports Capacitor directly. https://github.com/ionic-team/cordova-res#capacitor
Last version not works as spects... this still works great!!!!

it is not working for me i have windows and i cant run the sudo chmod and when i run the npm this err appear
errno: -4058, code: 'ENOENT', syscall: 'copyfile', path: 'C:\\Users\\pc\\Documents\\Negocio\\Bolution\\Code\\bolution\\resources\\ios\\icon\\icon-20@2x.png', dest: 'C:\\Users\\pc\\Documents\\Negocio\\Bolution\\Code\\bolution\\ios\\App\\App\\Assets.xcassets\\AppIcon.appiconset\\AppIcon-20x20@2x.png' } npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! bolution@0.0.1 resources:cordova-res ios && cordova-res android && node scripts/resources.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the bolution@0.0.1 resources script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\pc\AppData\Roaming\npm-cache_logs\2020-07-21T00_30_34_827Z-debug.log`

You dont have a ios project generated... it means windows only Android ... so to generate it for iOS you need a MAC

@manormunoz
Copy link

Hero

@tnovau
Copy link

tnovau commented Nov 5, 2020

@Gabriel1590 cordova-res now supports Capacitor directly. https://github.com/ionic-team/cordova-res#capacitor

Thanks!

@aacassandra
Copy link

aacassandra commented Dec 19, 2020

@Gabriel1590 cordova-res now supports Capacitor directly. https://github.com/ionic-team/cordova-res#capacitor

Thanks!

Thankyou @dalezak, its awesome.

and for @tnovau, but cordova-res cannot generate foreground-icons
as mentioned here
ionic-team/capacitor-assets#137 (comment)

Thanks!

@itshazlan
Copy link

@dalezak @rrlevy
That works pretty well. Nice work. With the splash images generated using cordova-res I noticed these are just cropped not resized.
This makes for some pretty awful looking splash screens at the lower resolutions.
Is there any way to to resize the image like image gorilla does?
https://apetools.webprofusion.com/#/tools/imagegorilla

same here, for me cordova-res is just cropped the asset files not generated successfully :(

@flyer1
Copy link

flyer1 commented Mar 13, 2021

@dalezak @rrlevy
That works pretty well. Nice work. With the splash images generated using cordova-res I noticed these are just cropped not resized.
This makes for some pretty awful looking splash screens at the lower resolutions.

I was under the impression that cropping is the right approach. That's why the recommendations are to center your design. There is a PSD template in the ionic documentation that has a very simple grid that demonstrates the sweet spot of the splash screen

@willyguevara
Copy link

Super!!! 💯 !

@gitbatuhan
Copy link

What a great solution. Thanks @dalezak.

@guillaumeguiral
Copy link

Thanks, awesome. Still super useful

@Srinivas-newAge
Copy link

I dont have scripts/resources.js in my project

@Diex
Copy link

Diex commented Jan 25, 2022

I think it's outdated because of this:

Generated 18 resources for Android
WARN: Error occurred while copying resources/android/icon/mdpi-foreground.png
WARN: Error occurred while copying resources/android/icon/mdpi-background.png
WARN: Error occurred while copying resources/android/icon/hdpi-foreground.png
WARN: Error occurred while copying resources/android/icon/hdpi-background.png
WARN: Error occurred while copying resources/android/icon/xhdpi-foreground.png
WARN: Error occurred while copying resources/android/icon/xhdpi-background.png
WARN: Error occurred while copying resources/android/icon/xxhdpi-foreground.png
WARN: Error occurred while copying resources/android/icon/xxhdpi-background.png
WARN: Error occurred while copying resources/android/icon/xxxhdpi-foreground.png
WARN: Error occurred while copying resources/android/icon/xxxhdpi-background.png
Copied 31 resource items to Android

icon fails on android.
I'll check cordova-res for a solution.
any thought will be welcomed.

thx

@Srinivas-newAge
Copy link

Srinivas-newAge commented Jan 27, 2022

@Diex Thanks in advance ...waiting for solution

@gbrits
Copy link

gbrits commented Feb 9, 2022

@Srinivas-newAge @Diex you can use this alternative solution:

npm install capacitor-resources -g

Add the icon & splash to the resources folder as standard, then run the following command in your project's root

capacitor-resources

@theGuiMan
Copy link

i get this warning WARN: No config.xml file in directory. Skipping config.

@willyguevara
Copy link

willyguevara commented Oct 28, 2022

i get this warning WARN: No config.xml file in directory. Skipping config.

x2

i get it to work just commenting line 83 and 84 of fileresources.js

// copyImages(SOURCE_IOS_ICON, TARGET_IOS_ICON, IOS_ICONS);
// copyImages(SOURCE_IOS_SPLASH, TARGET_IOS_SPLASH, IOS_SPLASHES);

Because i was working only for android, not ios.

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