基于nodejs的psd切图功能
使用nodejs 切图
###简述
项目近期进行大量换皮,需要更高效率的切图,搜索了相关资料后决定使用nodejs下的psd2json模块用于切图,也因为工具链中ui编辑器支持json(需要修改导出规范,正在修改中,但需要美术按规范出psd文件,意义不大)。
经使用是节省了一部分重复性高的的工作 如调用ps已录制好动作进行切图,选择存放文件夹;
所需要的psd文件 还是需要手动整理好图层的;当然也可以通过命名规范,来提高开发效率。
或许导出规范弄好后,还可以在节省一部分排版的时间和创建一些控件的时间,因为美术已经排好版,我们可以直接使用位置信息,以及一些文本控件的属性(字体大小,颜色等)。
###环境搭建:
搭建nodejs 环境 http://www.runoob.com/nodejs/nodejs-tutorial.html;
使用npm 安装 psd2json(cmd窗口输入命令: npm i psd2json);
将path\node_modules.bin路径加入到环境变量
修改模块使其支持命令调用:
####1 修改psd2json模块文件夹中的文件
新增convert.js文件用于命令行调用
#!/usr/bin/env node
var psd2json = require("./index.js");
function run(argv) {
if (argv.length == 0) {
console.info('Usage: psd2json psdFile [outputFile] [--nopack] [--ignore-font] [#buildId]');
process.exit(0);
}
var psdFile = argv[0];
var outputFile;
var option = 0;
var options = {};
var buildId;
for (var i = 1; i < argv.length; i++) {
var arg = argv[i];
if (arg.indexOf('--') == 0) {
switch (arg.substr(2)) {
case 'nopack':
option |= psd2json.constants.NO_PACK;
break;
case 'ignore-font':
option |= psd2json.constants.IGNORE_FONT;
break;
default:
console.error('unknown argument: ' + arg);
process.exit(1);
break;
}
}
else if (arg.substr(0,1) == '#') {
buildId = arg.substr(1);
}
else {
if (!outputFile)
outputFile = arg;
else {
console.error('unknown argument: ' + arg);
process.exit(1);
}
}
}
psd2json.convert(psdFile, options)
.then(function (buildId) {
console.log('buildId: ' + buildId);
}).catch(console.err);
}
run(process.argv.slice(2));
修改index.js方法
const fs = require('fs');
const path = require('path');
const psd = require('psd');
const mkdirp = require('mkdirp');
/**
* Output PSD layout to JSON
* @param {string} psdFile Relative path or absolute path of PSD file
* @param {Object} [options] options
* @param {string} [options.outJsonDir] Set to output files
* @param {string} [options.outImgDir] Set to output files
*/
exports.convert = function (psdFile, options = {}) {
return new Promise(function (resolve, reject) {
const psdFilePath = path.resolve(psdFile);
const psdFileName = path.basename(psdFilePath, path.extname(psdFilePath));
var pathInfo = path.parse(psdFile);
if (!options.outImgDir) {
options.outImgDir = path.join(pathInfo.dir, pathInfo.name);
}
// get root node.
const psdData = psd.fromFile(psdFilePath);
psdData.parse();
const rootNode = psdData.tree();
const queueNodes = [];
const queueNodesIndex = [];
const queueNodesName = [];
const queueNodesStructure = [];
queueNodes.push(rootNode._children);
queueNodesIndex.push(0);
queueNodesName.push(undefined);
const psdStructure = {
'group' : []
};
queueNodesStructure.push(psdStructure);
queueLoop: while (0 < queueNodes.length) {
const queueIndex = queueNodes.length - 1;
const nodes = queueNodes[queueIndex];
const nodesStructure = queueNodesStructure[queueIndex];
let nodesIndex = queueNodesIndex[queueIndex];
let nodesName = queueNodesName[queueIndex];
if (nodesName === undefined) {
nodesName = '';
} else {
nodesName += path.sep;
}
while (nodesIndex < nodes.length) {
const node = nodes[nodesIndex];
nodesIndex++;
if (node.layer.visible === false) continue;
if (node.type === 'group') {
queueNodes.push(node._children);
queueNodesIndex[queueIndex] = nodesIndex;
queueNodesIndex.push(0);
queueNodesName.push(nodesName + node.name);
const structure = {
'name' : node.name,
'group' : []
};
nodesStructure.group.push(structure);
queueNodesStructure.push(structure);
continue queueLoop;
} else {
if (options.outImgDir) {
const outImgDirPath = options.outImgDir;
mkdirp.sync(outImgDirPath);
console.log('run' + path.join(outImgDirPath, node.name + '.png'));
node.layer.image.saveAsPng(path.join(outImgDirPath, node.name + '.png'));
}
const structure = {
'name' : node.name,
'x' : node.layer.left,
'y' : node.layer.top,
'width' : node.layer.width,
'height' : node.layer.height
};
nodesStructure.group.push(structure);
}
}
queueNodes.pop();
queueNodesIndex.pop();
queueNodesName.pop();
queueNodesStructure.pop();
}
const outJsonData = JSON.stringify(psdStructure.group);
if (options.outJsonDir) {
const outJsonDirPath = path.resolve(options.outJsonDir);
const outJsonPath = path.join(outJsonDirPath, psdFileName + '_ui_cfg.json');
// make output directory.
if (!fs.existsSync(outJsonDirPath)) {
fs.mkdirSync(outJsonDirPath);
}
// output file.
fs.writeFileSync(outJsonPath, outJsonData);
}
console.log('run');
});
}
####2 编写cmd命令调用js文件
在path\node_modules.bin文件夹中加入psd2json.cmd 命令文件
代码
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\..\psd2json\convert.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\psd2json\convert.js" %*
)
###使用:
在psd文件目录下打开cmd窗口 输入 psd2json @psd文件名字.psd
调用命令
调用成功
###PS
path为cmd窗口当前路径;
js 文件编写参考 psd2fgui模块;也可通过命令安装该模块:npm i psd2fgui
###参考:
http://gad.qq.com/article/detail/47830 快速转化PSD为UI界面
https://github.com/fairygui/psd2fgui psd2fgui地址