Bases: ContextPlugin, ColormanagedPyblishPluginMixin, OptionalPyblishPluginMixin
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.
Source code in client/ayon_photoshop/plugins/publish/extract_image.py
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
152 | class ExtractImage(
pyblish.api.ContextPlugin,
publish.ColormanagedPyblishPluginMixin,
publish.OptionalPyblishPluginMixin
):
"""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"]
formats = ["png", "jpg", "tga", "exr", "tif"]
settings_category = "photoshop"
optional = False
def process(self, context):
# Filter instances
filtered_instances = []
for instance in context:
if (
instance.data["productBaseType"] != "image"
or not self.is_active(instance.data)
):
continue
filtered_instances.append(instance)
if not filtered_instances:
return
stub = photoshop.stub()
all_layers = stub.get_layers() # Fetch once, reuse for all instances
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():
for instance in filtered_instances:
suffix = instance.data["name"]
staging_dir = self.staging_dir(instance)
self.log.info(f"Outputting image to {staging_dir}")
ids = set()
# real layers and groups
members = instance.data.get("members")
if members:
ids.update(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))
if not ids:
self.log.debug(
f"Instance {instance} has no publishable layers, "
f"skipping."
)
continue
# Context manager handles all visibility: show instance path,
# hide siblings, restore original state on exit
with photoshop.isolated_layers_visibility(stub, ids, all_layers):
# Perform extraction
files = {}
file_basename, workfile_extension = os.path.splitext(
stub.get_active_document_name()
)
workfile_extension = workfile_extension.strip(".")
self.log.debug(f"Extracting formats {self.formats} for {instance}")
for extension in self.formats:
self.log.debug(f"Extracting {extension} for {instance}")
repre_filename = f"{file_basename}_{suffix}.{extension}"
files[extension] = repre_filename
full_filename = os.path.join(
staging_dir, repre_filename)
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}")
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)
@classmethod
def get_attr_defs_for_context(cls, create_context: "CreateContext"):
return []
@classmethod
def get_attr_defs_for_instance(
cls, create_context: "CreateContext", instance: "CreatedInstance"
):
if instance.product_base_type != "image":
return []
return cls.get_attribute_defs()
|
Provide a temporary directory in which to store extracted files
Upon calling this method the staging directory is stored inside the instance.data['stagingDir']
Source code in client/ayon_photoshop/plugins/publish/extract_image.py
131
132
133
134
135
136
137
138
139
140 | 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)
|