|
13 | 13 | #### XCF ####
|
14 | 14 | def openLayer_XCF(file: str) -> LayeredImage:
|
15 | 15 | """Open an .xcf file into a layered image."""
|
16 |
| - from gimpformats.gimpXcfDocument import GimpDocument |
| 16 | + from gimpformats.gimpXcfDocument import GimpDocument, GimpGroup |
17 | 17 |
|
18 | 18 | blendLookup = {
|
19 | 19 | 0: BlendType.NORMAL,
|
@@ -67,66 +67,44 @@ def openLayer_XCF(file: str) -> LayeredImage:
|
67 | 67 | project = GimpDocument(file)
|
68 | 68 | # Iterate the layers and create a list of layers for each group, then remove
|
69 | 69 | # these from the project layers
|
70 |
| - layers = project.layers[::-1] |
71 |
| - index = 0 |
72 |
| - groupIndex = 0 |
73 |
| - groupLayers = [[]] |
74 |
| - while index < len(layers): |
75 |
| - layerOrGroup = layers[index] |
76 |
| - if layerOrGroup.isGroup: |
77 |
| - index -= 1 |
78 |
| - while layers[index].itemPath is not None: |
79 |
| - layer = layers[index] |
80 |
| - groupLayers[groupIndex].append( |
| 70 | + |
| 71 | + root_group = project.walkTree() |
| 72 | + |
| 73 | + def rec_walk(group: GimpGroup) -> list[Group | Layer]: |
| 74 | + layers = [] |
| 75 | + for child in group.children[::-1]: |
| 76 | + if isinstance(child, GimpGroup): |
| 77 | + info = child.layer_options |
| 78 | + if info is not None: |
| 79 | + layers.append( |
| 80 | + Group( |
| 81 | + name=str(info.name), |
| 82 | + layers=rec_walk(child), |
| 83 | + dimensions=(info.width, info.height), |
| 84 | + offsets=(0, 0), |
| 85 | + opacity=info.opacity, |
| 86 | + visible=info.visible, |
| 87 | + blendmode=blendModeLookup(info.blendMode, blendLookup), |
| 88 | + ) |
| 89 | + ) |
| 90 | + else: |
| 91 | + layers.append( |
81 | 92 | Layer(
|
82 |
| - name=layer.name, |
83 |
| - image=layer.image, |
84 |
| - dimensions=(layer.width, layer.height), |
| 93 | + name=str(child.name), |
| 94 | + image=child.image, |
| 95 | + dimensions=(child.width, child.height), |
85 | 96 | offsets=(
|
86 |
| - layer.xOffset - layerOrGroup.xOffset, |
87 |
| - layer.yOffset - layerOrGroup.yOffset, |
| 97 | + child.xOffset, |
| 98 | + child.yOffset, |
88 | 99 | ),
|
89 |
| - opacity=layer.opacity, |
90 |
| - visible=layer.visible, |
91 |
| - blendmode=blendModeLookup(layer.blendMode, blendLookup), |
| 100 | + opacity=child.opacity, |
| 101 | + visible=child.visible, |
| 102 | + blendmode=blendModeLookup(child.blendMode, blendLookup), |
92 | 103 | )
|
93 | 104 | )
|
94 |
| - layers.pop(index) |
95 |
| - index -= 1 |
96 |
| - index += 2 |
97 |
| - groupIndex += 1 |
98 |
| - groupLayers.append([]) |
99 |
| - else: |
100 |
| - index += 1 |
101 |
| - # Iterate the clean project layers and add the group layers in |
102 |
| - groupIndex = 0 |
103 |
| - layersAndGroups = [] |
104 |
| - for layerOrGroup in layers: |
105 |
| - if layerOrGroup.isGroup: |
106 |
| - layersAndGroups.append( |
107 |
| - Group( |
108 |
| - name=layerOrGroup.name, |
109 |
| - layers=groupLayers[groupIndex][::-1], |
110 |
| - dimensions=(layerOrGroup.width, layerOrGroup.height), |
111 |
| - offsets=(layerOrGroup.xOffset, layerOrGroup.yOffset), |
112 |
| - opacity=layerOrGroup.opacity, |
113 |
| - visible=layerOrGroup.visible, |
114 |
| - blendmode=blendModeLookup(layerOrGroup.blendMode, blendLookup), |
115 |
| - ) |
116 |
| - ) |
117 |
| - groupIndex += 1 |
118 |
| - else: |
119 |
| - layersAndGroups.append( |
120 |
| - Layer( |
121 |
| - name=layerOrGroup.name, |
122 |
| - image=layerOrGroup.image, |
123 |
| - dimensions=(layerOrGroup.width, layerOrGroup.height), |
124 |
| - offsets=(layerOrGroup.xOffset, layerOrGroup.yOffset), |
125 |
| - opacity=layerOrGroup.opacity, |
126 |
| - visible=layerOrGroup.visible, |
127 |
| - blendmode=blendModeLookup(layerOrGroup.blendMode, blendLookup), |
128 |
| - ) |
129 |
| - ) |
| 105 | + return layers |
| 106 | + |
| 107 | + layersAndGroups = rec_walk(root_group) |
130 | 108 |
|
131 | 109 | return LayeredImage(layersAndGroups, (project.width, project.height))
|
132 | 110 |
|
|
0 commit comments