def launch(application): """Starts the web server that will be hosted in the Photoshop extension. """ from avalon import api, photoshop api.install(photoshop) # Launch Photoshop and the html server. process = subprocess.Popen(application, stdout=subprocess.PIPE) server = html_server.app.start_server(5000) # Wait for application launch to show Workfiles. if os.environ.get("AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH", False): # Wait for Photoshop launch. if photoshop.app(): workfiles.show(save=False) # Wait for Photoshop launch. if photoshop.app(): api.emit("application.launched") self.callback_queue = queue.Queue() while True: main_thread_listen() # Wait on Photoshop to close before closing the html server. process.wait() server.shutdown()
def process(self, instance): errored_plugins = get_errored_plugins_from_data(instance.context) if errored_plugins: raise RuntimeError( "Skipping incrementing current file because publishing failed." ) scene_path = version_up(instance.context.data["currentFile"]) photoshop.app().ActiveDocument.SaveAs(scene_path) self.log.info("Incremented workfile to: {}".format(scene_path))
def process(self, instance): staging_dir = self.staging_dir(instance) self.log.info("Outputting image to {}".format(staging_dir)) # Perform extraction files = {} with photoshop.maintained_selection(): self.log.info("Extracting %s" % str(list(instance))) with photoshop.maintained_visibility(): # Hide all other layers. extract_ids = [ x.id for x in photoshop.get_layers_in_layers([instance[0]]) ] for layer in photoshop.get_layers_in_document(): if layer.id not in extract_ids: layer.Visible = False save_options = {} if "png" in self.formats: save_options["png"] = photoshop.com_objects.PNGSaveOptions() if "jpg" in self.formats: save_options["jpg"] = photoshop.com_objects.JPEGSaveOptions() file_basename = os.path.splitext( photoshop.app().ActiveDocument.Name )[0] for extension, save_option in save_options.items(): _filename = "{}.{}".format(file_basename, extension) files[extension] = _filename full_filename = os.path.join(staging_dir, _filename) photoshop.app().ActiveDocument.SaveAs( full_filename, save_option, True ) representations = [] for extension, filename in files.items(): representations.append({ "name": extension, "ext": extension, "files": filename, "stagingDir": staging_dir }) instance.data["representations"] = representations instance.data["stagingDir"] = staging_dir self.log.info(f"Extracted {instance} to {staging_dir}")
def launch(application): """Starts the web server that will be hosted in the Photoshop extension. """ from avalon import api, photoshop api.install(photoshop) sys.excepthook = safe_excepthook # Launch Photoshop and the html server. process = subprocess.Popen(application, stdout=subprocess.PIPE) server = html_server.app.start_server(5000) while True: if process.poll() is not None: print("Photoshop process is not alive. Exiting") server.shutdown() sys.exit(1) try: _app = photoshop.app() if _app: break except Exception: time.sleep(0.1) # Wait for application launch to show Workfiles. if os.environ.get("AVALON_PHOTOSHOP_WORKFILES_ON_LAUNCH", False): # Wait for Photoshop launch. if photoshop.app(): workfiles.show(save=False) # Wait for Photoshop launch. if photoshop.app(): api.emit("application.launched") self.callback_queue = queue.Queue() while True: main_thread_listen() # Wait on Photoshop to close before closing the html server. process.wait() server.shutdown()
def process(self): groups = [] layers = [] create_group = False group_constant = photoshop.get_com_objects().constants().psLayerSet if (self.options or {}).get("useSelection"): multiple_instances = False selection = photoshop.get_selected_layers() if len(selection) > 1: # Ask user whether to create one image or image per selected # item. msg_box = Qt.QtWidgets.QMessageBox() msg_box.setIcon(Qt.QtWidgets.QMessageBox.Warning) msg_box.setText( "Multiple layers selected." "\nDo you want to make one image per layer?" ) msg_box.setStandardButtons( Qt.QtWidgets.QMessageBox.Yes | Qt.QtWidgets.QMessageBox.No | Qt.QtWidgets.QMessageBox.Cancel ) ret = msg_box.exec_() if ret == Qt.QtWidgets.QMessageBox.Yes: multiple_instances = True elif ret == Qt.QtWidgets.QMessageBox.Cancel: return if multiple_instances: for item in selection: if item.LayerType == group_constant: groups.append(item) else: layers.append(item) else: group = photoshop.group_selected_layers() group.Name = self.name groups.append(group) elif len(selection) == 1: # One selected item. Use group if its a LayerSet (group), else # create a new group. if selection[0].LayerType == group_constant: groups.append(selection[0]) else: layers.append(selection[0]) elif len(selection) == 0: # No selection creates an empty group. create_group = True else: create_group = True if create_group: group = photoshop.app().ActiveDocument.LayerSets.Add() group.Name = self.name groups.append(group) for layer in layers: photoshop.select_layers([layer]) group = photoshop.group_selected_layers() group.Name = layer.Name groups.append(group) for group in groups: photoshop.imprint(group, self.data)
def process(self, context): context.data["currentFile"] = os.path.normpath( photoshop.app().ActiveDocument.FullName ).replace("\\", "/")
def process(self, instance): staging_dir = self.staging_dir(instance) self.log.info("Outputting image to {}".format(staging_dir)) layers = [] for image_instance in instance.context: if image_instance.data["family"] != "image": continue layers.append(image_instance[0]) # Perform extraction output_image = "{}.jpg".format( os.path.splitext(photoshop.app().ActiveDocument.Name)[0] ) output_image_path = os.path.join(staging_dir, output_image) with photoshop.maintained_visibility(): # Hide all other layers. extract_ids = [ x.id for x in photoshop.get_layers_in_layers(layers) ] for layer in photoshop.get_layers_in_document(): if layer.id in extract_ids: layer.Visible = True else: layer.Visible = False photoshop.app().ActiveDocument.SaveAs( output_image_path, photoshop.com_objects.JPEGSaveOptions(), True ) ffmpeg_path = pype.lib.get_ffmpeg_tool_path("ffmpeg") instance.data["representations"].append({ "name": "jpg", "ext": "jpg", "files": output_image, "stagingDir": staging_dir }) instance.data["stagingDir"] = staging_dir # Generate thumbnail. thumbnail_path = os.path.join(staging_dir, "thumbnail.jpg") args = [ ffmpeg_path, "-y", "-i", output_image_path, "-vf", "scale=300:-1", "-vframes", "1", thumbnail_path ] output = pype.lib._subprocess(args) self.log.debug(output) instance.data["representations"].append({ "name": "thumbnail", "ext": "jpg", "files": os.path.basename(thumbnail_path), "stagingDir": staging_dir, "tags": ["thumbnail"] }) # Generate mov. mov_path = os.path.join(staging_dir, "review.mov") args = [ ffmpeg_path, "-y", "-i", output_image_path, "-vf", "pad=ceil(iw/2)*2:ceil(ih/2)*2", "-vframes", "1", mov_path ] output = pype.lib._subprocess(args) self.log.debug(output) instance.data["representations"].append({ "name": "mov", "ext": "mov", "files": os.path.basename(mov_path), "stagingDir": staging_dir, "frameStart": 1, "frameEnd": 1, "fps": 25, "preview": True, "tags": ["review", "ftrackreview"] }) # Required for extract_review plugin (L222 onwards). instance.data["frameStart"] = 1 instance.data["frameEnd"] = 1 instance.data["fps"] = 25 self.log.info(f"Extracted {instance} to {staging_dir}")