参考工程
https://github.com/Banbury/UnityPsdImporter
PSD文件结构的详细文档
https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_38034
准备psd样本
我使用的psd文件结构如下
问题1.列表转树
psd中不管是Group(分组),Image,还是Text文字,都抽象为Layer(图层)
使用上面的开源库中PSDFile文件解析后,我们得到了List
但我们更希望拿到一个树状的结构,因此我们需要把上述List结构转化为Tree
List结构转Tree
总体我们使用一个stack生成tree
倒序
观察列表和psd结构,我们发现列表是树状结构的遍历之后的倒序,所以我们先把列表Reverse一下
</Layer group>图层
从log中可以看到,中有一些layer的name是</Layer group>,这是特殊的layer,期对应的属性是Section divider(可以从Layer的AdditionalInfo属性中找到)。
这个特殊Layer的作用是分割符,代表分组结束。
算法描述
扫描列表中的layer
如果layer的section是OpenFolder或者ClosedFolder,入栈。
栈顶的layer是当前layer的父节点
如果layer的sectioninfo是section divder,从栈中弹出
`public static TreeNode<Layer> GetTreeStructure(PsdFile file)
{
Stack<TreeNode<Layer>> stack = new Stack<TreeNode<Layer>>();
TreeNode<Layer> root = new TreeNode<Layer>();
stack.Push(root);
List<Layer> layers = new List<Layer>(file.Layers.ToArray());
layers.Reverse();
int count = layers.Count;
for (int i = 0; i < count; i++)
{
Layer layer = layers[i];
LayerSectionInfo sectionInfo = FindSection(layer);
if (sectionInfo != null && sectionInfo.SectionType == LayerSectionType.SectionDivider)
{
stack.Pop();
continue;
}
TreeNode<Layer> node = new TreeNode<Layer>(layer);
stack.Peek().AddChild(node);
if (sectionInfo != null && (sectionInfo.SectionType == LayerSectionType.OpenFolder || sectionInfo.SectionType == LayerSectionType.ClosedFolder))
{
stack.Push(node);
}
}
stack.Pop();
return root;
}`