Exemplo n.º 1
0
    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
Exemplo n.º 2
0
            errors.append(
                "Failed to construct export path for layer '%s': %s" %
                (layer_name, e))
            return errors

        # ensure the export folder exists:
        export_folder = os.path.dirname(export_path)
        self.parent.ensure_folder_exists(export_folder)

        # get a path in the temp dir to use for the thumbnail:
        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
        # printerTool("More info", "Got here...")

        try:
            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)
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
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