Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Automatically generate non-retina and Android images for Alloy projects
function downsize(event, logger) {
var wrench = require("wrench"),
path = require("path"),
fs = require("fs"),
imagemagick = require("imagemagick"),
U = require('../../utils');
// Generator
function generator(source, target, percentage) {
// File (or 9-patch version) doesn't exist or (non 9-patch) file is older
if (!fs.existsSync(target.replace(/(\.png)$/, '.9$1')) && (!fs.existsSync(target) || (fs.statSync(source).mtime > fs.statSync(target).mtime))) {
if (percentage === '100%') {
logger.info('Copying: ' + target);
U.copyFileSync(source, target);
} else {
logger.info('Downsizing ' + percentage + ': ' + target);
var target_dir = path.dirname(target);
if (!path.existsSync(target_dir)) {
wrench.mkdirSyncRecursive(target_dir, 0777);
}
imagemagick.convert([source, '-resize', percentage, target], function(error, m) {
error && logger.error('Failed generating "' + target + '" because of: ' + error.message);
});
}
}
}
// Walker
function walk(dir) {
wrench.readdirSyncRecursive(dir).forEach(function(file) {
// Catch retina files, except for iPhone 5 (retina only) ones
if (file.indexOf('@2x') > 0 && file.indexOf('-568h@2x') < 0) {
var source = path.join(dir, file);
var target = path.join(dir, file.replace('@2x', ''));
// iOS
if (event.alloyConfig.platform === 'ios') {
// Non-retina
generator(source, target, '50%');
// Android
} else if (event.alloyConfig.platform === 'android') {
target = target.replace(/(\/iphone)?(\/images)(\/.+\/)?(.+)$/, '/android$2/_DENSITY_$3$4');
// xhdpi
generator(source, target.replace('_DENSITY_', 'res-xhdpi'), '100%');
// hdpi
generator(source, target.replace('_DENSITY_', 'res-hdpi'), '75%');
// mdpi
generator(source, target.replace('_DENSITY_', 'res-mdpi'), '50%');
}
}
});
}
// Un-retina /app to find main assets as well as in themes and widgets
walk(event.dir.home);
}
task("pre:load", function(event, logger) {
downsize(event, logger);
});

UPDATE: With the assets command of the TiCons CLI / Module this can be done even simpeler by calling $ ticons assets or an alloy.ymk using:

task("pre:load", function(event, logger) {
    require('ticons').assets();
});

Automatically generate non-retina and Android images for Alloy projects

This [Alloy Build Configuration File](http://docs.appcelerator.com/titanium/3.0/#!/guide/Build_Configuration_File_(alloy.jmk) automatically generates non-retina and Android XHDPI, HDPI and MDPI images for all new and changed retina (@2x) images before each compile.

Read more about it at: http://fokkezb.nl/2013/07/29/generate-non-retina-images/

@botmaster

This comment has been minimized.

Copy link

@botmaster botmaster commented Dec 9, 2013

It's working like a charm when I compile for ios.
it does not work when compiling for android. The Retina file is copied to the same folder without '@2x'.
Ex: /Users/name/Documents/Titanium_Studio_Workspace/Test JMK Unretina/app/assets/img/test.png

[edit]
Ok sorry, my images have to be in "images" folder, not "img". ^^

Really handy script.

@jayeshIT

This comment has been minimized.

Copy link

@jayeshIT jayeshIT commented Jan 20, 2014

i put images folder in assest/images and android and iphone folder are empty it work's fine for iPhone but for android it generate @2x images ..what is problem ?

@HazemKhaled

This comment has been minimized.

Copy link

@HazemKhaled HazemKhaled commented Mar 3, 2014

I think we have to add way to ignore some images, for example i need to force size of image with more details for Android.

@vivekgidmare

This comment has been minimized.

Copy link

@vivekgidmare vivekgidmare commented Apr 22, 2014

[ERROR] : ' event
[ERROR] : : spawn ENOENT
[ERROR] : Alloy compiler failed

I got this Error

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