9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 | class ExtractImage(
pyblish.api.ContextPlugin,
publish.ColormanagedPyblishPluginMixin
):
"""Extract all layers (groups) marked for publish.
Usually publishable instance is created as a wrapper of layer(s). For each
publishable instance so many images as there is 'formats' is created.
Logic tries to hide/unhide layers minimum times.
Called once for all publishable instances.
"""
order = publish.Extractor.order - 0.48
label = "Extract Image"
hosts = ["photoshop"]
families = ["image", "background"]
formats = ["png", "jpg", "tga"]
settings_category = "photoshop"
def process(self, context):
stub = photoshop.stub()
hidden_layer_ids = set()
all_layers = stub.get_layers()
for layer in all_layers:
if not layer.visible:
hidden_layer_ids.add(layer.id)
stub.hide_all_others_layers_ids([], layers=all_layers)
native_colorspace = stub.get_color_profile_name()
self.log.info(f"Document colorspace profile: {native_colorspace}")
host_name = context.data["hostName"]
project_settings = context.data["project_settings"]
host_imageio_settings = project_settings["photoshop"]["imageio"]
with photoshop.maintained_selection():
with photoshop.maintained_visibility(layers=all_layers):
for instance in context:
if instance.data["productType"] not in self.families:
continue
suffix = instance.data["name"]
staging_dir = self.staging_dir(instance)
self.log.info("Outputting image to {}".format(staging_dir))
# Perform extraction
files = {}
ids = set()
# real layers and groups
members = instance.data("members")
if members:
ids.update(set([int(member) for member in members]))
# virtual groups collected by color coding or auto_image
add_ids = instance.data.pop("ids", None)
if add_ids:
ids.update(set(add_ids))
extract_ids = set([ll.id for ll in stub.
get_layers_in_layers_ids(ids, all_layers)
if ll.id not in hidden_layer_ids])
for extracted_id in extract_ids:
stub.set_visible(extracted_id, True)
file_basename, workfile_extension = os.path.splitext(
stub.get_active_document_name()
)
workfile_extension = workfile_extension.strip(".")
for extension in self.formats:
repre_filename = f"{file_basename}_{suffix}.{extension}"
files[extension] = repre_filename
full_filename = os.path.join(
staging_dir, repre_filename)
if extension == "tga":
self._save_image_to_targa(
stub,
full_filename,
extension,
workfile_extension
)
else:
stub.saveAs(full_filename, extension, True)
self.log.info(f"Extracted: {extension}")
representations = []
for extension, filename in files.items():
repre = {
"name": extension,
"ext": extension,
"files": filename,
"stagingDir": staging_dir,
"tags": [],
}
ayon_colorspace = get_remapped_colorspace_from_native(
native_colorspace,
host_name,
host_imageio_settings,
)
self.log.debug(f"ayon_colorspace: {ayon_colorspace}")
# inject colorspace data
self.set_representation_colorspace(
repre, context,
colorspace=ayon_colorspace
)
self.log.debug(f"representation: {repre}")
representations.append(repre)
instance.data["representations"] = representations
instance.data["stagingDir"] = staging_dir
self.log.info(f"Extracted {instance} to {staging_dir}")
for extracted_id in extract_ids:
stub.set_visible(extracted_id, False)
def staging_dir(self, instance):
"""Provide a temporary directory in which to store extracted files
Upon calling this method the staging directory is stored inside
the instance.data['stagingDir']
"""
from ayon_core.pipeline.publish import get_instance_staging_dir
return get_instance_staging_dir(instance)
def _save_image_to_targa(self, stub, full_filename, extension, workfile_extension):
"""Hacky way to save image in targa. Save the psd file
in quiet mode with targa options first and then convert it into targa
***Caution to use it.
Args:
stub (RPC stub): stub to call method
full_filename (str): full published filename
extension (str): published extension
workfile_extension (str): workfile extension
"""
src_file = full_filename.replace(extension, workfile_extension)
stub.saveAs(full_filename, extension, True)
if os.path.exists(src_file):
os.rename(src_file, full_filename)
|