def transform(self, data, options=None): if self._validate(data) is None: return None if self.format is None: return None width = self.width height = self.height # Allow to override the size settings via the options dict if options is not None: width = options.get("width", width) height = options.get("height", height) result = TransformResult(None) try: # If we already got a file-like iterator use it if isinstance(data, file): orig = data else: orig = StringIO() orig.writelines(data) orig.seek(0) try: pil_image = Image.open(orig) except IOError, e: result.errors = str(e) log_debug("Error %s while transforming an Image in %s." % (str(e), self.name)) return result transparency = pil_image.info.get("transparency", False) if self.format in ["jpeg", "ppm"]: pil_image.draft("RGB", pil_image.size) pil_image = pil_image.convert("RGB") if width is None: width = pil_image.size[0] if height is None: height = pil_image.size[1] if width and height: pil_image.thumbnail((width, height), Image.ANTIALIAS) transformed = StringIO() # Only use transparency in the supported modes if self.format == "png" and pil_image.mode not in ("P", "L"): pil_image.save(transformed, self.format) else: pil_image.save(transformed, self.format, transparency=transparency) transformed.seek(0)
def __init__(self): super(CommandTransform, self).__init__() if self.command is None: log_debug("There was no command given for the %s transform." % self.name) else: if bin_search(self.command): self.available = True else: log_debug("The binary %s could not be found, while trying to " "use the %s transform." % (self.command, self.name))
def find_transform(self, input_mimetype, output_mimetype, use_ranked=True): """ The find_transform method returns the transform which is going to be used for a particular input / output mimetype combination. """ available = self.available_transforms() available_inputs = [spec[0] for spec in available] available_outputs = [spec[1] for spec in available] # Is the input and output format available? if input_mimetype not in available_inputs or output_mimetype not in available_outputs: log_debug( "No transforms could be found to transform the " "'%s' format into the '%s' format." % (input_mimetype, output_mimetype) ) return None # Special behavior for filters, which have an identical input and # output encoding matches = [] if input_mimetype == output_mimetype: matches = [spec[2] for spec in available if spec[0] == input_mimetype and spec[1] == input_mimetype] if len(matches) > 0: return matches[0] # Find all transforms which match the input format matches = [spec for spec in available if spec[0] == input_mimetype] paths = [] if len(matches) > 0: # TODO Add recursive algorithms, so non-direct matches are found as well for spec in matches: if spec[1] == output_mimetype: paths.append(spec[2]) # Sort by some criteria if len(paths) > 0: def _criteria(value): ranked = IRankedTransform.providedBy(value) rank = 100 if ranked: rank = value.rank return rank if use_ranked: paths.sort(key=_criteria) return paths[0] log_debug( "No transforms could be found to transform the '%s' " "format into the '%s' format." % (input_mimetype, output_mimetype) ) return None
def _validate(self, data): """Checks if the transform itself is available and the passed in data is of the right type. """ if not self.available: return None # Invalid input if data is None: log_debug("No input while transforming data in %s." % self.name) return None elif isinstance(data, basestring): log_debug("Invalid input while transforming data in %s." % self.name) return None return True