用了photoshop那么久,从来没仔细想过它到底用了哪些算法。想一想就觉得倒抽一口凉气。
传闻photoshop的创始人,和wps创始人一样,就一个程序员写好了这第一版的成品。同样是做人,咋就差距这么大呢?
千古疑问
- 所以这个.psd文件的格式是什么,它和png、jpg、gif,甚至json文件的格式上有什么区别?
- .psd文件是怎么做到分层的,分层的存储方式又是啥?
- 如何把.psd文件的单层图另外存储起来成为多个sprite?(没错就是Unity中的sprite)以及如何对其进行轮廓检测呢?(unity是如何做到的呢?)
在危险的ps插件边缘试探
作为一个见得不够多脑子也不够灵活的菜鸡,我决定 “旁征博引” “凿壁偷光”,先康康有哪些源码可以让我学习学习~这要从psd文件导入unity的一个插件说起!
我们把一个很神秘的文件放进了photoshop的这个generator路径下,那么这个文件里面都有啥呢?
(JavaScript) main.jsx
(function() {
"use strict";
// *** PACKAGES ***
var fs = require("fs");
var path = require("path");
var pluginPackage = require("./package.json");
// *** CONSTANTS ***
var MENU_ID = pluginPackage.name; // our plugin's menu id
var MENU_STRING = "Ps2D Map"; // our plugin's menu text
var PLUGIN_VERSION = pluginPackage.version; // our plugin version
var PLUGIN_NAME = pluginPackage.name; // plugin name
var MAP_EXTENSION = ".ps2dmap.json"; // map's extension
// *** STATE VARIABLES ***
var _generator = null; // the generator framework
var _currentDocumentId = null; // the document's id
var _currentDocumentFile = null; // the document's filename
// *** PLUGIN FUNCTIONALITY
// kick it off!
function run() {
// request the document from photoshop
_generator.getDocumentInfo(_currentDocumentId)
.then(function(document) {
_currentDocumentFile = document.file;
var layoutDocument = createLayoutDocument(document);
saveMapFile(layoutDocument);
popup("The Ps2D map file has been created. Hurray!");
})
.done();
}
// Get the full filename for the layout file we create.
// It will be written in the same directory as the PSD file.
function layoutFilename() {
var myExtension = path.extname(_currentDocumentFile);
var myBasename = path.basename(_currentDocumentFile, myExtension);
var myPath = path.dirname(_currentDocumentFile);
return myPath + path.sep + myBasename + MAP_EXTENSION;
}
// save the layout to the file system
function saveMapFile(layoutDocument) {
// get the filename
var filename = layoutFilename();
// serialize our layoutDocument to a string
var contents = JSON.stringify(layoutDocument);
try
{
// a synchronous node.js call? finally, sanity!!! just kidding. mostly.
fs.writeFileSync(filename, contents);
} catch (err)
{
// TODO: It'd be nice to show people a message instead of just logging
log("unable to save map file to " + filename);
}
}
// convert the photoshop document to our own layout document
function createLayoutDocument(document) {
// create our own document
var layoutDocument = {
};
layoutDocument.pluginVersion = PLUGIN_VERSION;
layoutDocument.bounds = document.bounds;
layoutDocument.mask = document.mask;
layoutDocument.sprites = convertLayersToSprites(document.layers);
return layoutDocument;
}
// convert a list of layers into a list of sprites
function convertLayersToSprites(layers) {
// sanity
if (layers === null || layers === undefined || layers.length === 0)
return null;
// sprites go here
var sprites = [];
// go through each layer
for (var i = 0, z = layers.length; i < z; i++)
{
var layer = layers[i];
// convert it
var sprite = convertLayerToSprite(layer);
// add it to the list if it's legit
if (sprite !== null) {
sprites.push(sprite);
}
}
return sprites;
}
// convert a ps layer to a sprite
function convertLayerToSprite(layer) {
// safety
if (layer === null || layer === undefined) return null;
// grab what we need for our map
var sprite = {
};
sprite.id = layer.id;
sprite.name = layer.name;
sprite.bounds = layer.bounds;
sprite.mask = layer.mask;
sprite.visible = layer.visible;
sprite.sprites = convertLayersToSprites(layer.layers);
return sprite;
}
// *** EVENT HANDLERS ***
// fires when we've installed successfully
function handleMenuItemInstallSuccess() {
}
// fires when PS can't install our menu item
function handleMenuItemInstallFailed() {
log("Unable to create Ps2D menu item.");
}
// the user has clicked our menu item
function handleGeneratorMenuClicked(e) {
// which menu item caused this event?
var menu = e.generatorMenuChanged;
// if it wasn't us, jet.
if (!menu || menu.name !== MENU_ID) return;
// ok, it's go time!