def _cinema_find_additional_scene_dependencies(self): """ Find additional dependencies from the scene """ # initial implementation does nothing! return [] ################################################################################# # create a version! jpg_pub_path = os.path.join(tempfile.gettempdir(), "%s_sgtk.jpg" % uuid.uuid4().hex) thumbnail_file = photoshop.RemoteObject('flash.filesystem::File', jpg_pub_path) jpeg_options = photoshop.RemoteObject( 'com.adobe.photoshop::JPEGSaveOptions') # save as a copy photoshop.app.activeDocument.saveAs(thumbnail_file, jpeg_options, True) # then register version progress_cb(60.0, "Creating Version...") ctx = self.parent.context data = { "user": ctx.user, "description": comment, "sg_first_frame": 1, "frame_count": 1, "frame_range": "1-1", "sg_last_frame": 1, "entity": ctx.entity, "sg_path_to_frames": publish_path, "project": ctx.project, "sg_task": sg_task, "code": tank_publish["code"], "created_by": ctx.user, } if tank.util.get_published_file_entity_type( self.parent.tank) == "PublishedFile": data["published_files"] = [tank_publish] else: # == "TankPublishedFile" data["tank_published_file"] = tank_publish version = self.parent.shotgun.create("Version", data) # upload jpeg progress_cb(70.0, "Uploading to Shotgun...") self.parent.shotgun.upload("Version", version['id'], jpg_pub_path, "sg_uploaded_movie") try: os.remove(jpg_pub_path) except: pass progress_cb(100) return publish_path
def __send_to_review(self, primary_publish_path, sg_task, comment, p4, p4_fw, progress_cb): """ Create a version of the current document that can be uploaded as a Shotgun 'Version' entity and reviewed in Screening Room, etc. """ errors = [] progress_cb(10, "Saving JPEG version of file") # set up the export options and get a file object: jpeg_path = os.path.join(tempfile.gettempdir(), "%s_sgtk.jpg" % uuid.uuid4().hex) jpeg_file = photoshop.RemoteObject('flash.filesystem::File', jpeg_path) jpeg_save_options = photoshop.RemoteObject('com.adobe.photoshop::JPEGSaveOptions') jpeg_save_options.quality = 12 try: # save as a copy: photoshop.app.activeDocument.saveAs(jpeg_file, jpeg_save_options, True) # construct the data needed to create a Shotgun 'Version' entity: ctx = self.parent.context data = { "code":os.path.basename(primary_publish_path), "sg_first_frame": 1, "frame_count": 1, "frame_range": "1-1", "sg_last_frame": 1, "entity": ctx.entity, "sg_path_to_frames": primary_publish_path, "project": ctx.project, "sg_task": sg_task, "sg_uploaded_movie": jpeg_path } # and store the version data for the publish path: progress_cb(50.0, "Storing review data...") try: p4_fw.store_publish_review_data(primary_publish_path, data) except TankError, e: errors.append("Failed to store review data: %s" % e) finally: # delete the temp jpeg file: if os.path.exists(jpeg_path): try: os.remove(jpeg_path) except: pass return errors
def _do_photoshop_post_publish(self, work_template, progress_cb): """ Do any Photoshop post-publish work :param work_template: The primary work template used for the publish :param progress_cb: Callback to be used when reporting progress """ import photoshop progress_cb(0, "Versioning up the scene file") # get the current scene path: doc = photoshop.app.activeDocument if doc is None: raise TankError("There is no currently active document!") scene_path = doc.fullName.nativePath # increment version and construct new file name: progress_cb(25, "Finding next version number") fields = work_template.get_fields(scene_path) next_version = self._get_next_work_file_version(work_template, fields) fields["version"] = next_version new_scene_path = work_template.apply_fields(fields) # log info self.parent.log_debug("Version up work file %s --> %s..." % (scene_path, new_scene_path)) # rename and save the file progress_cb(50, "Saving the scene file") new_file_name = photoshop.RemoteObject('flash.filesystem::File', new_scene_path) # no options and do not save as a copy # http://cssdk.host.adobe.com/sdk/1.5/docs/WebHelp/references/csawlib/com/adobe/photoshop/Document.html#saveAs() doc.saveAs(new_file_name, None, False) progress_cb(100)
def add_file_to_photoshop(self, file_path, shotgun_data): """ Load item into Photoshop. """ import photoshop f = photoshop.RemoteObject('flash.filesystem::File', file_path) photoshop.app.load(f)
def _open_file(self, path, sg_publish_data): """ Import contents of the given file into the scene. :param path: Path to file. :param sg_publish_data: Shotgun data dictionary with all the standard publish fields. """ if not os.path.exists(path): raise Exception("File not found on disk - '%s'" % path) import photoshop f = photoshop.RemoteObject('flash.filesystem::File', path) photoshop.app.load(f)
def execute(self, operation, file_path, **kwargs): """ Main hook entry point :operation: String Scene operation to perform :file_path: String File path to use if the operation requires it (e.g. open) :returns: Depends on operation: 'current_path' - Return the current scene file path as a String all others - None """ if operation == "current_path": # return the current script path doc = self._get_active_document() if doc.fullName is None: # not saved? path = "" else: path = doc.fullName.nativePath return path elif operation == "open": # reopen the specified script doc = self._get_active_document() doc.close() f = photoshop.RemoteObject('flash.filesystem::File', file_path) photoshop.app.load(f) elif operation == "save": # save the current script: doc = self._get_active_document() doc.save()
def bootstrap_tank(): try: import tank except Exception as e: msgbox("Shotgun: Could not import sgtk! Disabling for now: %s" % e) return if not "TANK_ENGINE" in os.environ: msgbox("Shotgun: Missing required environment variable TANK_ENGINE.") return engine_name = os.environ.get("TANK_ENGINE") try: context = tank.context.deserialize(os.environ.get("TANK_CONTEXT")) except Exception as e: msgbox( "Shotgun: Could not create context! Shotgun Pipeline Toolkit will be disabled. Details: %s" % e) return try: engine = tank.platform.start_engine(engine_name, context.tank, context) except Exception as e: msgbox("Shotgun: Could not start Photoshop engine: %s" % e) return file_to_open = os.environ.get("TANK_FILE_TO_OPEN") if file_to_open: import photoshop f = photoshop.RemoteObject("flash.filesystem::File", file_to_open) photoshop.app.load(f) # clean up temp env vars for var in ["TANK_ENGINE", "TANK_CONTEXT", "TANK_FILE_TO_OPEN"]: if var in os.environ: del os.environ[var]
return engine_name = os.environ.get("TANK_ENGINE") try: context = tank.context.deserialize(os.environ.get("TANK_CONTEXT")) except Exception, e: msgbox( "Shotgun: Could not create context! Shotgun Pipeline Toolkit will be disabled. Details: %s" % e) return try: engine = tank.platform.start_engine(engine_name, context.tank, context) except Exception, e: msgbox("Shotgun: Could not start engine: %s" % e) return file_to_open = os.environ.get("TANK_FILE_TO_OPEN") if file_to_open: import photoshop f = photoshop.RemoteObject("flash.filesystem::File", file_to_open) photoshop.app.load(f) # clean up temp env vars for var in ["TANK_ENGINE", "TANK_CONTEXT", "TANK_FILE_TO_OPEN"]: if var in os.environ: del os.environ[var] bootstrap_tank()
def _extract_photoshop_thumbnail(self): """ Extract a thumbnail from the current doc in Photoshop :returns str: The path to the thumbnail on disk """ import photoshop MAX_THUMB_SIZE = 512 # set unit system to pixels: original_ruler_units = photoshop.app.preferences.rulerUnits pixel_units = photoshop.StaticObject('com.adobe.photoshop.Units', 'PIXELS') photoshop.app.preferences.rulerUnits = pixel_units try: active_doc = photoshop.app.activeDocument orig_name = active_doc.name width_str = active_doc.width height_str = active_doc.height # build temp name for the thumbnail doc (just in case we fail to close it!): name, sfx = os.path.splitext(orig_name) thumb_name = "%s_tkthumb.%s" % (name, sfx) # find the doc size in pixels # Note: this doesn't handle measurements other than pixels. doc_width = doc_height = 0 exp = re.compile("^(?P<value>[0-9]+) px$") mo = exp.match(width_str) if mo: doc_width = int(mo.group("value")) mo = exp.match(height_str) if mo: doc_height = int(mo.group("value")) thumb_width = thumb_height = 0 if doc_width and doc_height: max_sz = max(doc_width, doc_height) if max_sz > MAX_THUMB_SIZE: scale = min(float(MAX_THUMB_SIZE) / float(max_sz), 1.0) thumb_width = max(min(int(doc_width * scale), doc_width), 1) thumb_height = max( min(int(doc_height * scale), doc_height), 1) # get a path in the temp dir to use for the thumbnail: png_pub_path = os.path.join(tempfile.gettempdir(), "%s_sgtk.png" % uuid.uuid4().hex) # get a file object from Photoshop for this path and the current PNG save options: thumbnail_file = photoshop.RemoteObject('flash.filesystem::File', png_pub_path) png_options = photoshop.RemoteObject( 'com.adobe.photoshop::PNGSaveOptions') # duplicate the original doc: save_options = photoshop.flexbase.requestStatic( 'com.adobe.photoshop.SaveOptions', 'DONOTSAVECHANGES') thumb_doc = active_doc.duplicate(thumb_name) try: # flatten image: thumb_doc.flatten() # resize if needed: if thumb_width and thumb_height: thumb_doc.resizeImage("%d px" % thumb_width, "%d px" % thumb_height) # save: thumb_doc.saveAs(thumbnail_file, png_options, True) finally: # close the doc: thumb_doc.close(save_options) return png_pub_path finally: # set units back to original photoshop.app.preferences.rulerUnits = original_ruler_units
def execute(self, operation, file_path, context, parent_action, file_version, read_only, **kwargs): """ Main hook entry point :operation: String Scene operation to perform :file_path: String File path to use if the operation requires it (e.g. open) :context: Context The context the file operation is being performed in. :parent_action: This is the action that this scene operation is being executed for. This can be one of: - open_file - new_file - save_file_as - version_up :file_version: The version/revision of the file to be opened. If this is 'None' then the latest version should be opened. :read_only: Specifies if the file should be opened read-only or not :returns: Depends on operation: 'current_path' - Return the current scene file path as a String 'reset' - True if scene was reset to an empty state, otherwise False all others - None """ p4_fw = self.load_framework(TK_FRAMEWORK_PERFORCE_NAME) if operation == "current_path": # return the current script path doc = self._get_active_document() if doc.fullName is None: # new file? path = "" else: path = doc.fullName.nativePath return path elif operation == "open": # check that we have the correct version synced: p4 = p4_fw.connection.connect() if read_only: pass ## just sync the file: ## (TODO) - move this to the framework #path_to_sync = file_path #if file_version: # # sync specific version: # path_to_sync = "%s#%s" % (path_to_sync, file_version) #try: # p4.run_sync(path_to_sync) #except P4Exception, e: # raise TankError("Failed to sync file '%s'" % path_to_sync) else: # open the file for edit: #p4_fw.util.open_file_for_edit(p4, file_path, add_if_new=False, version=file_version) p4_fw.util.open_file_for_edit(p4, file_path, add_if_new=False) # open the file f = photoshop.RemoteObject('flash.filesystem::File', file_path) photoshop.app.load(f) elif operation == "save": # save the current script: doc = self._get_active_document() doc.save() elif operation == "save_as": doc = self._get_active_document() # and check out the file for edit: p4 = p4_fw.connection.connect() p4_fw.util.open_file_for_edit(p4, file_path, add_if_new=False) photoshop.save_as(doc, file_path) elif operation == "reset": # do nothing and indicate scene was reset to empty return True elif operation == "prepare_new": # file->new. Not sure how to pop up the actual file->new UI, # this command will create a document with default properties photoshop.app.documents.add()
def create_thumbnail(self, name="", targetpath=None, MAX_THUMB_SIZE=256): errors = [] if name == "": name = "thumbDouble" # get a path in the temp dir to use for the thumbnail: thumbnail_path = "" if targetpath != None: thumbnail_path = targetpath else: thumbnail_path = os.path.join(tempfile.gettempdir(), "%s_sgtk.png" % uuid.uuid4().hex) # set unit system to pixels: original_ruler_units = photoshop.app.preferences.rulerUnits pixel_units = photoshop.StaticObject('com.adobe.photoshop.Units', 'PIXELS') photoshop.app.preferences.rulerUnits = pixel_units try: active_doc = photoshop.app.activeDocument orig_name = active_doc.name width_str = active_doc.width height_str = active_doc.height # calculate the thumbnail doc size: doc_width = doc_height = 0 exp = re.compile("^(?P<value>[0-9]+) px$") mo = exp.match(width_str) if mo: doc_width = int(mo.group("value")) mo = exp.match(height_str) if mo: doc_height = int(mo.group("value")) thumb_width = thumb_height = 0 if doc_width and doc_height: max_sz = max(doc_width, doc_height) if max_sz > MAX_THUMB_SIZE: scale = min(float(MAX_THUMB_SIZE) / float(max_sz), 1.0) thumb_width = max(min(int(doc_width * scale), doc_width), 1) thumb_height = max( min(int(doc_height * scale), doc_height), 1) # set up the thumbnail options and get a file object: thumbnail_file = photoshop.RemoteObject('flash.filesystem::File', thumbnail_path) png_save_options = photoshop.RemoteObject( 'com.adobe.photoshop::PNGSaveOptions') close_save_options = photoshop.flexbase.requestStatic( 'com.adobe.photoshop.SaveOptions', 'DONOTSAVECHANGES') # duplicate doc doc_name, doc_sfx = os.path.splitext(orig_name) thumb_doc_name = "%s_%s.%s" % (doc_name, name, doc_sfx) thumb_doc = active_doc.duplicate(thumb_doc_name) try: # flatten thumb_doc.flatten() # resize for thumbnail if thumb_width and thumb_height: thumb_doc.resizeImage("%d px" % thumb_width, "%d px" % thumb_height) # save again (as thumbnail) thumb_doc.saveAs(thumbnail_file, png_save_options, True) finally: # close the doc: thumb_doc.close(close_save_options) except: errors.append("Failed to construct thumbnail for '%s': %s" % (name, e)) return errors return thumbnail_path
mo = exp.match(height_str) if mo: doc_height = int(mo.group("value")) thumb_width = thumb_height = 0 if doc_width and doc_height: max_sz = max(doc_width, doc_height) if max_sz > MAX_THUMB_SIZE: scale = min(float(MAX_THUMB_SIZE) / float(max_sz), 1.0) thumb_width = max(min(int(doc_width * scale), doc_width), 1) thumb_height = max( min(int(doc_height * scale), doc_height), 1) # set up the export options and get a file object: layer_file = photoshop.RemoteObject('flash.filesystem::File', export_path) # printerTool(export_path, "Export Path :") progress_cb(20, "Exporting %s layer" % layer_name) close_save_options = photoshop.flexbase.requestStatic( 'com.adobe.photoshop.SaveOptions', 'DONOTSAVECHANGES') file_save_options = None # duplicate doc doc_name, doc_sfx = os.path.splitext(orig_name) layer_doc_name = "%s_%s.%s" % (doc_name, layer_name, doc_sfx) layer_doc = active_doc.duplicate(layer_doc_name) currentBitsPerChannel = layer_doc.bitsPerChannel try: if export_path.endswith(".png"): file_save_options = photoshop.RemoteObject(
class PublishHook(Hook): """ Single hook that implements publish functionality for secondary tasks """ def execute(self, tasks, work_template, comment, thumbnail_path, sg_task, primary_task, primary_publish_path, progress_cb, **kwargs): """ Main hook entry point :param tasks: List of secondary tasks to be published. Each task is a dictionary containing the following keys: { item: Dictionary This is the item returned by the scan hook { name: String description: String type: String other_params: Dictionary } output: Dictionary This is the output as defined in the configuration - the primary output will always be named 'primary' { name: String publish_template: template tank_type: String } } :param work_template: template This is the template defined in the config that represents the current work file :param comment: String The comment provided for the publish :param thumbnail: Path string The default thumbnail provided for the publish :param sg_task: Dictionary (shotgun entity description) The shotgun task to use for the publish :param primary_publish_path: Path string This is the path of the primary published file as returned by the primary publish hook :param progress_cb: Function A progress callback to log progress during pre-publish. Call: progress_cb(percentage, msg) to report progress to the UI :param primary_task: The primary task that was published by the primary publish hook. Passed in here for reference. This is a dictionary in the same format as the secondary tasks above. :returns: A list of any tasks that had problems that need to be reported in the UI. Each item in the list should be a dictionary containing the following keys: { task: Dictionary This is the task that was passed into the hook and should not be modified { item:... output:... } errors: List A list of error messages (strings) to report } """ results = [] active_doc = photoshop.app.activeDocument scene_path = active_doc.fullName.nativePath # publish all tasks: for task in tasks: item = task["item"] output = task["output"] errors = [] # report progress: progress_cb(0, "Publishing", task) # merged doc as tif if output["name"] == "tif_output": # publish the layer as a tif: output_errors = self.__publish_merged_as_tif( work_template, output["publish_template"], scene_path, active_doc, sg_task, comment, progress_cb) if output_errors: errors += output_errors # groups elif output["name"] == "export_groups": # publish the layer as a tif: export_errors = self.__publish_group_as_tif( item["name"], work_template, output["publish_template"], scene_path, active_doc, primary_publish_path, sg_task, comment, progress_cb) if export_errors: errors += export_errors else: # don't know how to publish this output types! errors.append("Don't know how to publish this item!") # if there is anything to report then add to result if len(errors) > 0: # add result: results.append({"task": task, "errors": errors}) progress_cb(100) return results def __publish_merged_as_tif(self, work_template, publish_template, scene_path, active_doc, sg_task, comment, progress_cb): """ Publish the flattened doc as a tif """ errors = [] progress_cb(10, "Building output path") # generate the export path using the correct template together # with the fields extracted from the work template: export_path = None try: fields = work_template.get_fields(scene_path) fields = dict( chain( fields.items(), self.parent.context.as_template_fields( publish_template).items())) #fields["TankType"] = publish_type export_path = publish_template.apply_fields(fields).encode("utf8") except TankError, e: errors.append("Failed to construct export path: %s" % (e)) return errors # ensure the export folder exists: export_folder = os.path.dirname(export_path) self.parent.ensure_folder_exists(export_folder) # set unit system to pixels: original_ruler_units = photoshop.app.preferences.rulerUnits pixel_units = photoshop.StaticObject('com.adobe.photoshop.Units', 'PIXELS') photoshop.app.preferences.rulerUnits = pixel_units try: orig_name = active_doc.name width_str = active_doc.width height_str = active_doc.height # set up the export options and get a file object: tiff_file = photoshop.RemoteObject('flash.filesystem::File', export_path) tiff_save_options = photoshop.RemoteObject( 'com.adobe.photoshop::TiffSaveOptions') tiff_save_options.layers = False close_save_options = photoshop.flexbase.requestStatic( 'com.adobe.photoshop.SaveOptions', 'DONOTSAVECHANGES') progress_cb(20, "Exporting to tif") # duplicate doc doc_name, doc_sfx = os.path.splitext(orig_name) temp_doc_name = "%s_temp.%s" % (doc_name, doc_sfx) temp_doc = active_doc.duplicate(temp_doc_name) try: # flatten temp_doc.flatten() # save: temp_doc.saveAs(tiff_file, tiff_save_options, True) finally: # close the doc: temp_doc.close(close_save_options) finally: # set units back to original photoshop.app.preferences.rulerUnits = original_ruler_units return errors
def execute(self, operation, file_path, context, parent_action, **kwargs): """ Main hook entry point :operation: String Scene operation to perform :file_path: String File path to use if the operation requires it (e.g. open) :context: Context The context the file operation is being performed in. :parent_action: This is the action that this scene operation is being executed for. This can be one of: - open_file - new_file - save_file_as - version_up :returns: Depends on operation: 'current_path' - Return the current scene file path as a String 'reset' - True if scene was reset to an empty state, otherwise False all others - None """ if operation == "current_path": # return the current script path doc = self._get_active_document() if doc.fullName is None: # new file? path = "" else: path = doc.fullName.nativePath return path elif operation == "open": # open the specified script f = photoshop.RemoteObject('flash.filesystem::File', file_path) photoshop.app.load(f) elif operation == "save": # save the current script: doc = self._get_active_document() doc.save() elif operation == "save_as": doc = self._get_active_document() new_file_name = photoshop.RemoteObject('flash.filesystem::File', file_path) # no options and do not save as a copy # http://cssdk.host.adobe.com/sdk/1.5/docs/WebHelp/references/csawlib/com/adobe/photoshop/Document.html#saveAs() doc.saveAs(new_file_name, None, False) elif operation == "reset": # do nothing and indicate scene was reset to empty return True elif operation == "prepare_new": # file->new. Not sure how to pop up the actual file->new UI, # this command will create a document with default properties photoshop.app.documents.add()
if mo: doc_width = int(mo.group("value")) mo = exp.match (height_str) if mo: doc_height = int(mo.group("value")) thumb_width = thumb_height = 0 if doc_width and doc_height: max_sz = max(doc_width, doc_height) if max_sz > MAX_THUMB_SIZE: scale = min(float(MAX_THUMB_SIZE)/float(max_sz), 1.0) thumb_width = max(min(int(doc_width * scale), doc_width), 1) thumb_height = max(min(int(doc_height * scale), doc_height), 1) # set up the export options and get a file object: layer_file = photoshop.RemoteObject('flash.filesystem::File', export_path) tiff_save_options = photoshop.RemoteObject('com.adobe.photoshop::TiffSaveOptions') tiff_save_options.layers = False # set up the thumbnail options and get a file object: thumbnail_file = photoshop.RemoteObject('flash.filesystem::File', thumbnail_path) png_save_options = photoshop.RemoteObject('com.adobe.photoshop::PNGSaveOptions') close_save_options = photoshop.flexbase.requestStatic('com.adobe.photoshop.SaveOptions', 'DONOTSAVECHANGES') progress_cb(20, "Exporting %s layer" % layer_name) # duplicate doc doc_name, doc_sfx = os.path.splitext(orig_name) layer_doc_name = "%s_%s.%s" % (doc_name, layer_name, doc_sfx) layer_doc = active_doc.duplicate(layer_doc_name)
def execute(self, operation, file_path, context, parent_action, file_version, read_only, **kwargs): """ Main hook entry point :param operation: String Scene operation to perform :param file_path: String File path to use if the operation requires it (e.g. open) :param context: Context The context the file operation is being performed in. :param parent_action: This is the action that this scene operation is being executed for. This can be one of: - open_file - new_file - save_file_as - version_up :param file_version: The version/revision of the file to be opened. If this is 'None' then the latest version should be opened. :param read_only: Specifies if the file should be opened read-only or not :returns: Depends on operation: 'current_path' - Return the current scene file path as a String 'reset' - True if scene was reset to an empty state, otherwise False all others - None """ if operation == "current_path": # return the current script path doc = self._get_active_document() if doc.fullName is None: # new file? path = "" else: path = doc.fullName.nativePath return path elif operation == "open": # open the specified script f = photoshop.RemoteObject('flash.filesystem::File', file_path) photoshop.app.load(f) elif operation == "save": # save the current script: doc = self._get_active_document() doc.save() elif operation == "save_as": doc = self._get_active_document() photoshop.save_as(doc, file_path) elif operation == "reset": # do nothing and indicate scene was reset to empty return True elif operation == "prepare_new": # file->new. Not sure how to pop up the actual file->new UI, # this command will create a document with default properties photoshop.app.documents.add()
tank_publish = self._register_publish(publish_path, publish_name, sg_task, fields["version"], output["tank_type"], comment, thumbnail_path, dependency_paths=[]) ################################################################################# # create a version! jpg_pub_path = os.path.join(tempfile.gettempdir(), "%s_sgtk.jpg" % uuid.uuid4().hex) thumbnail_file = photoshop.RemoteObject('flash.filesystem::File', jpg_pub_path) jpeg_options = photoshop.RemoteObject( 'com.adobe.photoshop::JPEGSaveOptions') # save as a copy photoshop.app.activeDocument.saveAs(thumbnail_file, jpeg_options, True) # then register version progress_cb(60.0, "Creating Version...") ctx = self.parent.context data = { "user": ctx.user, "description": comment, "sg_first_frame": 1, "frame_count": 1, "frame_range": "1-1", "sg_last_frame": 1,
export_folder = os.path.dirname(export_path) self.parent.ensure_folder_exists(export_folder) # set unit system to pixels: original_ruler_units = photoshop.app.preferences.rulerUnits pixel_units = photoshop.StaticObject('com.adobe.photoshop.Units', 'PIXELS') photoshop.app.preferences.rulerUnits = pixel_units try: orig_name = active_doc.name width_str = active_doc.width height_str = active_doc.height # set up the export options and get a file object: group_file = photoshop.RemoteObject('flash.filesystem::File', export_path) tiff_save_options = photoshop.RemoteObject( 'com.adobe.photoshop::TiffSaveOptions') tiff_save_options.layers = False # trying to get transcparency, but non of the below seems to be working... #tiff_save_options.transparency = True #tiff_save_options.alphaChannels = True close_save_options = photoshop.flexbase.requestStatic( 'com.adobe.photoshop.SaveOptions', 'DONOTSAVECHANGES') progress_cb(40, "Exporting %s group" % group_name) # duplicate doc doc_name, doc_sfx = os.path.splitext(orig_name) group_doc_name = "%s_%s.%s" % (doc_name, group_name, doc_sfx)