libreflow.extensions.sk.export-psd-layers 1.1.7__tar.gz → 1.1.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/CHANGELOG.md +14 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7/src/libreflow.extensions.sk.export_psd_layers.egg-info → libreflow_extensions_sk_export_psd_layers-1.1.9}/PKG-INFO +15 -1
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow/extensions/sk/export_psd_layers/__init__.py +253 -61
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow/extensions/sk/export_psd_layers/_version.py +3 -3
- libreflow_extensions_sk_export_psd_layers-1.1.9/src/libreflow/extensions/sk/export_psd_layers/scripts/PSD_crop_layers.jsx +37 -0
- libreflow_extensions_sk_export_psd_layers-1.1.9/src/libreflow/extensions/sk/export_psd_layers/scripts/__init__.py +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9/src/libreflow.extensions.sk.export_psd_layers.egg-info}/PKG-INFO +15 -1
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow.extensions.sk.export_psd_layers.egg-info/SOURCES.txt +3 -1
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/MANIFEST.in +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/README.md +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/setup.cfg +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/setup.py +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow/__init__.py +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow/extensions/__init__.py +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow/extensions/sk/__init__.py +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow.extensions.sk.export_psd_layers.egg-info/dependency_links.txt +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow.extensions.sk.export_psd_layers.egg-info/requires.txt +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/src/libreflow.extensions.sk.export_psd_layers.egg-info/top_level.txt +0 -0
- {libreflow_extensions_sk_export_psd_layers-1.1.7 → libreflow_extensions_sk_export_psd_layers-1.1.9}/versioneer.py +0 -0
|
@@ -19,6 +19,20 @@ Types of changes
|
|
|
19
19
|
|
|
20
20
|
## [Unreleased]
|
|
21
21
|
|
|
22
|
+
## [1.1.9] - 2025-10-17
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
* Cropping process in extend script into Photoshop for oversize layers, in BG layout task.
|
|
27
|
+
|
|
28
|
+
## [1.1.8] - 2025-10-07
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
|
|
32
|
+
* Export resized to psd canvas - warning message for layers with a bouding box twice as large as the viewbox
|
|
33
|
+
|
|
34
|
+
## [1.1.7] - 2025-08-19
|
|
35
|
+
|
|
22
36
|
### Added
|
|
23
37
|
|
|
24
38
|
* Warning message when publishing regarding resolution and colour depth.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: libreflow.extensions.sk.export_psd_layers
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.9
|
|
4
4
|
Home-page: https://gitlab.com/lfs.coop/libreflow/libreflow_launcher
|
|
5
5
|
Author: Thomas Thiebaut
|
|
6
6
|
Author-email: autor@les-fees-speciales.coop
|
|
@@ -50,6 +50,20 @@ Types of changes
|
|
|
50
50
|
|
|
51
51
|
## [Unreleased]
|
|
52
52
|
|
|
53
|
+
## [1.1.9] - 2025-10-17
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
* Cropping process in extend script into Photoshop for oversize layers, in BG layout task.
|
|
58
|
+
|
|
59
|
+
## [1.1.8] - 2025-10-07
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
* Export resized to psd canvas - warning message for layers with a bouding box twice as large as the viewbox
|
|
64
|
+
|
|
65
|
+
## [1.1.7] - 2025-08-19
|
|
66
|
+
|
|
53
67
|
### Added
|
|
54
68
|
|
|
55
69
|
* Warning message when publishing regarding resolution and colour depth.
|
|
@@ -1,30 +1,103 @@
|
|
|
1
|
+
import gc
|
|
2
|
+
import json
|
|
1
3
|
import os
|
|
2
4
|
import re
|
|
3
|
-
import json
|
|
4
|
-
import gazu
|
|
5
5
|
import time
|
|
6
6
|
|
|
7
|
+
import gazu
|
|
7
8
|
from kabaret import flow
|
|
8
|
-
from libreflow.flows.default.flow.film import Film
|
|
9
9
|
from libreflow.baseflow.file import (
|
|
10
|
-
|
|
11
|
-
TrackedFile,
|
|
10
|
+
CreateWorkingCopyAction,
|
|
12
11
|
FileRevisionNameChoiceValue,
|
|
13
|
-
UploadPNGToKitsu,
|
|
14
12
|
PublishAndRenderPlayblast,
|
|
15
13
|
PublishFileAction,
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
TrackedFile,
|
|
15
|
+
UploadPNGToKitsu,
|
|
16
|
+
GenericRunAction,
|
|
17
|
+
WaitProcess,
|
|
18
18
|
)
|
|
19
|
+
from libreflow.flows.default.flow.film import Film
|
|
19
20
|
from psd_tools import PSDImage
|
|
20
|
-
from psd_tools.psd import PSD
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
|
|
23
|
+
class WaitCroppingAction(WaitProcess):
|
|
24
|
+
|
|
25
|
+
_file = flow.Parent()
|
|
26
|
+
|
|
27
|
+
def allow_context(self, context):
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
def get_run_label(self):
|
|
31
|
+
return 'Restart export layers'
|
|
32
|
+
|
|
33
|
+
def _do_after_process_ends(self, *args, **kwargs):
|
|
34
|
+
self._file.export_layers.run("Export")
|
|
35
|
+
|
|
36
|
+
class CroppingPSDLayers(GenericRunAction):
|
|
37
|
+
"""Crop layerswith a bouding box twice as large as the file size."""
|
|
38
|
+
|
|
39
|
+
ICON = ("icons.flow", "photoshop")
|
|
40
|
+
|
|
41
|
+
_file = flow.Parent()
|
|
42
|
+
|
|
43
|
+
file_path = flow.Param()
|
|
44
|
+
|
|
45
|
+
def allow_context(self, context):
|
|
46
|
+
return context
|
|
47
|
+
|
|
48
|
+
def runner_name_and_tags(self):
|
|
49
|
+
"""Get the name and tags for a runner.
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
str, list: name and tags for a runner
|
|
53
|
+
|
|
54
|
+
"""
|
|
55
|
+
return "Photoshop", []
|
|
56
|
+
|
|
57
|
+
def get_run_label(self):
|
|
58
|
+
return "Cropping Layers"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def extra_argv(self):
|
|
62
|
+
"""Build the list of command-line arguments required for export in Photoshop.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
list[str]: command-line arguments for the Photoshop export process.
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
current_directory = os.path.split(__file__)[0]
|
|
69
|
+
script_path = os.path.normpath(
|
|
70
|
+
os.path.join(current_directory, "scripts/PSD_crop_layers.jsx")
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return [self.file_path.get(), script_path]
|
|
74
|
+
|
|
75
|
+
def run(self, button):
|
|
76
|
+
"""Execute the render action.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
button (str): The label of the button pressed by the user (e.g., 'Export' or 'Cancel').
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Any: the result of the parent run method if executed, or None if canceled.
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
if button == "Cancel":
|
|
86
|
+
return
|
|
87
|
+
|
|
88
|
+
runner_dict = super(CroppingPSDLayers, self).run(button)
|
|
89
|
+
psb_runner = (
|
|
90
|
+
self.root().session().cmds.SubprocessManager.get_runner_info(runner_dict["runner_id"])
|
|
91
|
+
)
|
|
92
|
+
self._file.wait_cropping_action.wait_pid(psb_runner["pid"])
|
|
93
|
+
self._file.wait_cropping_action.run('wait')
|
|
94
|
+
|
|
95
|
+
return runner_dict
|
|
25
96
|
|
|
26
97
|
|
|
27
98
|
class ExportPSDLayers(flow.Action):
|
|
99
|
+
"""Exports Photoshop (PSD/PSB) layers for background layout and color tasks."""
|
|
100
|
+
|
|
28
101
|
ICON = ("icons.flow", "photoshop")
|
|
29
102
|
|
|
30
103
|
_file = flow.Parent()
|
|
@@ -36,6 +109,15 @@ class ExportPSDLayers(flow.Action):
|
|
|
36
109
|
revision = flow.Param(None, FileRevisionNameChoiceValue)
|
|
37
110
|
|
|
38
111
|
def allow_context(self, context):
|
|
112
|
+
"""Check whether the given context is valid for running the action.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
context: Context object, usually representing the current project/task.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
bool: True if the action can be executed in this context, False otherwise.
|
|
119
|
+
|
|
120
|
+
"""
|
|
39
121
|
return (
|
|
40
122
|
context
|
|
41
123
|
and self._file.format.get() in ["psd", "psb"]
|
|
@@ -43,24 +125,47 @@ class ExportPSDLayers(flow.Action):
|
|
|
43
125
|
self._file.get_revision_names(
|
|
44
126
|
sync_status="Available", published_only=True
|
|
45
127
|
)
|
|
46
|
-
)
|
|
128
|
+
)
|
|
129
|
+
> 0
|
|
47
130
|
)
|
|
48
131
|
|
|
49
132
|
def needs_dialog(self):
|
|
133
|
+
"""Indicate whether this action requires a dialog to be displayed.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
bool: always True.
|
|
137
|
+
|
|
138
|
+
"""
|
|
50
139
|
msg = ""
|
|
51
140
|
if self._task.name() == "bg_layout":
|
|
52
|
-
msg = "<b>Layout : Photoshop Project layers will be exported separately</b>
|
|
141
|
+
msg = """<b>Layout : Photoshop Project layers will be exported separately</b><br><br>
|
|
142
|
+
<font color=orange>If some layers are twice as large as the document size, Photoshop will be open to crop them.</font>
|
|
143
|
+
"""
|
|
53
144
|
elif self._task.name() == "bg_color":
|
|
54
|
-
msg =
|
|
55
|
-
|
|
145
|
+
msg = (
|
|
146
|
+
"<b>BG Color : Photoshop Project will be exported as a single image</b>"
|
|
147
|
+
)
|
|
148
|
+
|
|
56
149
|
self.message.set(msg)
|
|
57
150
|
return True
|
|
58
151
|
|
|
59
152
|
def get_buttons(self):
|
|
153
|
+
"""Return the buttons displayed in the dialog.
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
list[str]: list of button labels, typically ['Export', 'Cancel'].
|
|
157
|
+
|
|
158
|
+
"""
|
|
60
159
|
self.revision.revert_to_default()
|
|
61
160
|
return ["Export", "Cancel"]
|
|
62
161
|
|
|
63
162
|
def ensure_render_folder(self):
|
|
163
|
+
"""Ensure the render output folder exists for the current file.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
flow.File: The folder object where rendered files will be stored.
|
|
167
|
+
|
|
168
|
+
"""
|
|
64
169
|
folder_name = self._file.complete_name.get()
|
|
65
170
|
folder_name += "_render"
|
|
66
171
|
|
|
@@ -73,6 +178,12 @@ class ExportPSDLayers(flow.Action):
|
|
|
73
178
|
return self._files[folder_name]
|
|
74
179
|
|
|
75
180
|
def ensure_render_folder_revision(self):
|
|
181
|
+
"""Ensure the render folder has the correct revision.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
flow.Revision: The revision object in the render folder.
|
|
185
|
+
|
|
186
|
+
"""
|
|
76
187
|
folder = self.ensure_render_folder()
|
|
77
188
|
revision_name = self.revision.get()
|
|
78
189
|
source_revision = self._file.get_revision(self.revision.get())
|
|
@@ -90,37 +201,55 @@ class ExportPSDLayers(flow.Action):
|
|
|
90
201
|
self._files.touch()
|
|
91
202
|
|
|
92
203
|
return revision
|
|
93
|
-
|
|
204
|
+
|
|
94
205
|
def get_default_file(self):
|
|
206
|
+
"""Retrieve the default file for exporting a BG color image.
|
|
207
|
+
|
|
208
|
+
Returns:
|
|
209
|
+
flow.File or None: The default file object, or None if not found.
|
|
210
|
+
|
|
211
|
+
"""
|
|
95
212
|
mng = self.root().project().get_task_manager()
|
|
96
213
|
default_files = mng.default_files.get()
|
|
97
214
|
for file_name, task_names in default_files.items():
|
|
98
|
-
if
|
|
215
|
+
if "bg_color.png" in file_name:
|
|
99
216
|
task = default_files[file_name][0]
|
|
100
|
-
file_mapped_name = file_name.replace(".",
|
|
217
|
+
file_mapped_name = file_name.replace(".", "_")
|
|
101
218
|
break
|
|
102
219
|
|
|
103
220
|
dft_task = mng.default_tasks[task]
|
|
104
|
-
if not dft_task.files.has_mapped_name(file_mapped_name):
|
|
221
|
+
if not dft_task.files.has_mapped_name(file_mapped_name): # check default file
|
|
105
222
|
# print(f'Scene Builder - default task {task_name} has no default file {filename} -> use default template')
|
|
106
223
|
return None
|
|
107
224
|
|
|
108
225
|
dft_file = dft_task.files[file_mapped_name]
|
|
109
226
|
return dft_file
|
|
110
|
-
|
|
227
|
+
|
|
111
228
|
def _ensure_file(self, name, format, path_format, source_revision):
|
|
229
|
+
"""Ensure a file exists in the project with the given name and revision.
|
|
230
|
+
|
|
231
|
+
Args:
|
|
232
|
+
name (str): The base name of the file.
|
|
233
|
+
format (str): The file extension (e.g., "png").
|
|
234
|
+
path_format (str): The default path format for the file.
|
|
235
|
+
source_revision (flow.Revision): The source revision to copy comments from.
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
flow.Revision: The revision object created or retrieved.
|
|
239
|
+
|
|
240
|
+
"""
|
|
112
241
|
mapped_name = "%s_%s" % (name, format)
|
|
113
242
|
|
|
114
243
|
file = None
|
|
115
|
-
|
|
244
|
+
|
|
116
245
|
if not self._files.has_mapped_name(mapped_name):
|
|
117
246
|
if format:
|
|
118
247
|
file = self._files.add_file(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
248
|
+
name=name,
|
|
249
|
+
extension=format,
|
|
250
|
+
tracked=True,
|
|
251
|
+
default_path_format=path_format,
|
|
252
|
+
)
|
|
124
253
|
else:
|
|
125
254
|
file = self._files.add_folder(name, tracked=True)
|
|
126
255
|
else:
|
|
@@ -135,7 +264,7 @@ class ExportPSDLayers(flow.Action):
|
|
|
135
264
|
r = file.get_revision(revision_name)
|
|
136
265
|
|
|
137
266
|
r.comment.set(source_revision.comment.get())
|
|
138
|
-
|
|
267
|
+
|
|
139
268
|
file.ensure_last_revision_oid()
|
|
140
269
|
|
|
141
270
|
r.set_sync_status("Available")
|
|
@@ -148,13 +277,22 @@ class ExportPSDLayers(flow.Action):
|
|
|
148
277
|
os.remove(img_path)
|
|
149
278
|
|
|
150
279
|
self._files.touch()
|
|
151
|
-
|
|
280
|
+
|
|
152
281
|
return r
|
|
153
282
|
|
|
154
283
|
def run(self, button):
|
|
284
|
+
"""Execute the render action.
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
button (str): The label of the button pressed by the user (e.g., 'Export' or 'Cancel').
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
Any: the result of the parent run method if executed, or None if canceled.
|
|
291
|
+
|
|
292
|
+
"""
|
|
155
293
|
if button == "Cancel":
|
|
156
294
|
return
|
|
157
|
-
|
|
295
|
+
|
|
158
296
|
session = self.root().session()
|
|
159
297
|
log_format = "[EXPORT LAYERS] {message}"
|
|
160
298
|
|
|
@@ -171,23 +309,22 @@ class ExportPSDLayers(flow.Action):
|
|
|
171
309
|
# Open photoshop file
|
|
172
310
|
psb = PSDImage.open(source_revision.get_path())
|
|
173
311
|
|
|
174
|
-
|
|
175
312
|
############# BG LAYOUT PROCESS #############
|
|
176
313
|
|
|
177
|
-
if self._task.name() == "bg_layout"
|
|
314
|
+
if self._task.name() == "bg_layout":
|
|
178
315
|
|
|
179
316
|
render_revision = self.ensure_render_folder_revision()
|
|
180
317
|
# JSON structure for layers order
|
|
181
318
|
layers_data = {
|
|
182
319
|
"from": os.path.basename(source_revision.get_path()),
|
|
183
320
|
"layers": [],
|
|
184
|
-
"hidden_layers": []
|
|
321
|
+
"hidden_layers": [],
|
|
185
322
|
}
|
|
186
323
|
|
|
187
324
|
# Export image layers
|
|
188
325
|
if os.path.exists(render_revision.get_path()) is False:
|
|
189
326
|
os.makedirs(render_revision.get_path())
|
|
190
|
-
|
|
327
|
+
|
|
191
328
|
folder_name = os.path.basename(render_revision.get_path())
|
|
192
329
|
|
|
193
330
|
# frame_bbox = (0, 0, 0, 0)
|
|
@@ -209,22 +346,54 @@ class ExportPSDLayers(flow.Action):
|
|
|
209
346
|
# # frame_bbox[2] - 5,
|
|
210
347
|
# # frame_bbox[3] - 5,
|
|
211
348
|
# # )
|
|
212
|
-
|
|
349
|
+
|
|
213
350
|
# print(frame_bbox)
|
|
214
351
|
|
|
352
|
+
# Stop exporting action when find layers with a bouding box twice as large as the viewbox
|
|
353
|
+
layers_to_crop = []
|
|
354
|
+
for descendant in psb.descendants():
|
|
355
|
+
if not descendant.is_group():
|
|
356
|
+
v_left, v_top, v_right, v_bottom = psb.viewbox
|
|
357
|
+
v_width, v_height = v_right - v_left, v_bottom - v_top
|
|
358
|
+
|
|
359
|
+
bbox_left, bbox_top, bbox_right, bbox_bottom = descendant.bbox
|
|
360
|
+
bbox_width, bbox_height = (
|
|
361
|
+
bbox_right - bbox_left,
|
|
362
|
+
bbox_bottom - bbox_top,
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
if not (bbox_height <= v_height * 1.5 or bbox_width <= v_width * 1.5):
|
|
366
|
+
layers_to_crop.append(descendant)
|
|
367
|
+
|
|
368
|
+
if len(layers_to_crop) != 0:
|
|
369
|
+
for layer in layers_to_crop:
|
|
370
|
+
cropping_action = self._file.cropping_psd_layers
|
|
371
|
+
cropping_action.file_path.set(source_revision.get_path())
|
|
372
|
+
self._file.cropping_psd_layers.run("Export")
|
|
373
|
+
session.log_warning(log_format.format(
|
|
374
|
+
message=f"Open Photoshop to crop these layers : {layers_to_crop}"
|
|
375
|
+
)
|
|
376
|
+
)
|
|
377
|
+
session.log_info(log_format.format(
|
|
378
|
+
message="Following export processes will be displayed on the processes view."))
|
|
379
|
+
return self.get_result(close=True)
|
|
380
|
+
|
|
215
381
|
for layer in reversed(psb):
|
|
382
|
+
|
|
216
383
|
# Remove invalid characters
|
|
217
|
-
layer_name = layer.name.replace(
|
|
384
|
+
layer_name = layer.name.replace(" ", "-")
|
|
218
385
|
match_invalid = re.search(r"[~\"#%&*:<>?/\\{|}]+", layer.name)
|
|
219
386
|
if match_invalid:
|
|
220
|
-
layer_name = layer_name.replace(match_invalid.group(0),
|
|
387
|
+
layer_name = layer_name.replace(match_invalid.group(0), "")
|
|
221
388
|
|
|
222
389
|
output_path = os.path.join(
|
|
223
390
|
render_revision.get_path(),
|
|
224
391
|
"{folder}-{layer}.png".format(folder=folder_name, layer=layer_name),
|
|
225
392
|
)
|
|
226
393
|
|
|
227
|
-
session.log_info(
|
|
394
|
+
session.log_info(
|
|
395
|
+
log_format.format(message=f"Exporting layer {layer_name}")
|
|
396
|
+
)
|
|
228
397
|
|
|
229
398
|
if not layer.visible:
|
|
230
399
|
layer.visible = True
|
|
@@ -235,59 +404,67 @@ class ExportPSDLayers(flow.Action):
|
|
|
235
404
|
layer_name
|
|
236
405
|
)
|
|
237
406
|
|
|
238
|
-
image = layer.composite(viewport=psb.viewbox)
|
|
407
|
+
image = layer.composite(viewport=psb.viewbox, force=True)
|
|
239
408
|
image.save(output_path)
|
|
409
|
+
session.log_info(f"Layer {layer_name} exported !")
|
|
410
|
+
gc.collect()
|
|
240
411
|
|
|
241
|
-
|
|
242
412
|
# Export JSON data
|
|
243
413
|
json_object = json.dumps(layers_data)
|
|
244
414
|
json_path = os.path.join(render_revision.get_path(), "layers.json")
|
|
245
|
-
|
|
246
|
-
session.log_info(log_format.format(message=
|
|
415
|
+
|
|
416
|
+
session.log_info(log_format.format(message="Saving layers.json"))
|
|
247
417
|
with open(json_path, "w") as outfile:
|
|
248
418
|
outfile.write(json_object)
|
|
249
|
-
|
|
250
|
-
session.log_info(log_format.format(message=
|
|
251
|
-
|
|
419
|
+
|
|
420
|
+
session.log_info(log_format.format(message="Export complete"))
|
|
421
|
+
|
|
252
422
|
############# BG COLOR PROCESS #############
|
|
253
|
-
|
|
254
|
-
if self._task.name() == "bg_color"
|
|
423
|
+
|
|
424
|
+
if self._task.name() == "bg_color":
|
|
255
425
|
|
|
256
426
|
default_file = self.get_default_file()
|
|
257
427
|
|
|
258
428
|
if default_file is not None:
|
|
259
|
-
|
|
429
|
+
|
|
260
430
|
render_revision = self._ensure_file(
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
431
|
+
name="bg_color",
|
|
432
|
+
format="png",
|
|
433
|
+
path_format=default_file.path_format.get(),
|
|
434
|
+
source_revision=source_revision,
|
|
435
|
+
)
|
|
266
436
|
|
|
267
437
|
output_path = render_revision.get_path()
|
|
268
438
|
|
|
269
439
|
info_layer = psb.find("INFO")
|
|
270
|
-
if info_layer
|
|
440
|
+
if info_layer:
|
|
441
|
+
info_layer.visible = False
|
|
271
442
|
|
|
272
443
|
LO_layer = psb.find("REF_LAYOUT")
|
|
273
|
-
if LO_layer
|
|
444
|
+
if LO_layer:
|
|
445
|
+
LO_layer.visible = False
|
|
274
446
|
|
|
275
447
|
DES_layer = psb.find("REF_DESIGN")
|
|
276
|
-
if DES_layer
|
|
448
|
+
if DES_layer:
|
|
449
|
+
DES_layer.visible = False
|
|
277
450
|
|
|
278
451
|
chara_layer = psb.find("character")
|
|
279
|
-
if chara_layer
|
|
452
|
+
if chara_layer:
|
|
453
|
+
chara_layer.visible = False
|
|
280
454
|
|
|
281
455
|
utils_layer = psb.find("_utils")
|
|
282
|
-
if utils_layer
|
|
456
|
+
if utils_layer:
|
|
457
|
+
utils_layer.visible = False
|
|
283
458
|
|
|
284
|
-
image = psb.composite(viewport=psb.viewbox,force=True)
|
|
459
|
+
image = psb.composite(viewport=psb.viewbox, force=True)
|
|
285
460
|
image.save(output_path)
|
|
286
461
|
|
|
287
|
-
session.log_info(log_format.format(message=
|
|
462
|
+
session.log_info(log_format.format(message="Export complete"))
|
|
288
463
|
|
|
289
464
|
else:
|
|
290
|
-
self.root().session().log_error(
|
|
465
|
+
self.root().session().log_error(
|
|
466
|
+
"[Export PSD] BG Color Image default file do not exist"
|
|
467
|
+
)
|
|
291
468
|
|
|
292
469
|
return self.get_result(close=True)
|
|
293
470
|
|
|
@@ -874,6 +1051,19 @@ class CreateWorkingCopy(CreateWorkingCopyAction):
|
|
|
874
1051
|
self.from_revision.revert_to_default()
|
|
875
1052
|
|
|
876
1053
|
return ["Create", "Create from scratch", "Cancel"]
|
|
1054
|
+
|
|
1055
|
+
|
|
1056
|
+
def wait_cropping_action(parent):
|
|
1057
|
+
if isinstance(parent, TrackedFile) and "psb" in parent.name():
|
|
1058
|
+
r = flow.Child(WaitCroppingAction).ui(hidden=True)
|
|
1059
|
+
r.name = "wait_cropping_action"
|
|
1060
|
+
return r
|
|
1061
|
+
|
|
1062
|
+
def cropping_psd_layers(parent):
|
|
1063
|
+
if isinstance(parent, TrackedFile) and "psb" in parent.name():
|
|
1064
|
+
r = flow.Child(CroppingPSDLayers).ui(hidden=True)
|
|
1065
|
+
r.name = "cropping_psd_layers"
|
|
1066
|
+
return r
|
|
877
1067
|
|
|
878
1068
|
|
|
879
1069
|
def publish_psd_file(parent):
|
|
@@ -941,5 +1131,7 @@ def install_extensions(session):
|
|
|
941
1131
|
publish_and_export_preview,
|
|
942
1132
|
publish_psd_file,
|
|
943
1133
|
create_working_copy,
|
|
1134
|
+
cropping_psd_layers,
|
|
1135
|
+
wait_cropping_action,
|
|
944
1136
|
]
|
|
945
1137
|
}
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-
|
|
11
|
+
"date": "2025-10-17T16:21:16+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.1.
|
|
14
|
+
"full-revisionid": "86f2486d9a667581997faca7a4f075e3b863a22e",
|
|
15
|
+
"version": "1.1.9"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var activeDoc = app.activeDocument;
|
|
2
|
+
|
|
3
|
+
doc_width = activeDoc.width;
|
|
4
|
+
doc_height = activeDoc.height;
|
|
5
|
+
|
|
6
|
+
var layers_list = new Array;
|
|
7
|
+
|
|
8
|
+
main();
|
|
9
|
+
|
|
10
|
+
function main() {
|
|
11
|
+
CollectAllLayers(activeDoc)
|
|
12
|
+
for (var i = 0; i < layers_list.length; i++){
|
|
13
|
+
layer_width = layers_list[i].bounds[2] - layers_list[i].bounds[0];
|
|
14
|
+
layer_height = layers_list[i].bounds[3] - layers_list[i].bounds[1];
|
|
15
|
+
|
|
16
|
+
if (layer_width > doc_width * 1.5 || layer_height > doc_height * 1.5){
|
|
17
|
+
activeDoc.crop([0,0,doc_width, doc_height])
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
activeDoc.save()
|
|
21
|
+
executeAction(app.charIDToTypeID('quit'), undefined, DialogModes.NO);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Collect all layers in a document
|
|
25
|
+
function CollectAllLayers(obj){
|
|
26
|
+
for ( var i = obj.layers.length-1; 0 <= i; i--){
|
|
27
|
+
var layer = obj.layers[i];
|
|
28
|
+
if (layer.typename === "ArtLayer"){
|
|
29
|
+
layers_list.push(obj.layers[i]);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
CollectAllLayers(obj.layers[i]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return layers_list;
|
|
36
|
+
}
|
|
37
|
+
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: libreflow.extensions.sk.export_psd_layers
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.9
|
|
4
4
|
Home-page: https://gitlab.com/lfs.coop/libreflow/libreflow_launcher
|
|
5
5
|
Author: Thomas Thiebaut
|
|
6
6
|
Author-email: autor@les-fees-speciales.coop
|
|
@@ -50,6 +50,20 @@ Types of changes
|
|
|
50
50
|
|
|
51
51
|
## [Unreleased]
|
|
52
52
|
|
|
53
|
+
## [1.1.9] - 2025-10-17
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
* Cropping process in extend script into Photoshop for oversize layers, in BG layout task.
|
|
58
|
+
|
|
59
|
+
## [1.1.8] - 2025-10-07
|
|
60
|
+
|
|
61
|
+
### Fixed
|
|
62
|
+
|
|
63
|
+
* Export resized to psd canvas - warning message for layers with a bouding box twice as large as the viewbox
|
|
64
|
+
|
|
65
|
+
## [1.1.7] - 2025-08-19
|
|
66
|
+
|
|
53
67
|
### Added
|
|
54
68
|
|
|
55
69
|
* Warning message when publishing regarding resolution and colour depth.
|
|
@@ -13,4 +13,6 @@ src/libreflow.extensions.sk.export_psd_layers.egg-info/top_level.txt
|
|
|
13
13
|
src/libreflow/extensions/__init__.py
|
|
14
14
|
src/libreflow/extensions/sk/__init__.py
|
|
15
15
|
src/libreflow/extensions/sk/export_psd_layers/__init__.py
|
|
16
|
-
src/libreflow/extensions/sk/export_psd_layers/_version.py
|
|
16
|
+
src/libreflow/extensions/sk/export_psd_layers/_version.py
|
|
17
|
+
src/libreflow/extensions/sk/export_psd_layers/scripts/PSD_crop_layers.jsx
|
|
18
|
+
src/libreflow/extensions/sk/export_psd_layers/scripts/__init__.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|