def scaleImage(image, width=None, height=None, direction='down', quality=88, result=None): """Scale the given image data to another size and return the result as a string or optionally write in to the file-like `result` object. The `image` parameter can either be the raw image data (ie a `str` instance) or an open file. The `quality` parameter can be used to set the quality of the resulting image scales. The return value is a tuple with the new image, the image format and a size-tuple. Optionally a file-like object can be given as the `result` parameter, in which the generated image scale will be stored. The `width`, `height`, `direction` parameters will be passed to :meth:`scalePILImage`, which performs the actual scaling. The generated image is a JPEG image, unless the original is a PNG or GIF image. This is needed to make sure alpha channel information is not lost, which JPEG does not support. """ if isinstance(image, (bytes, str)): image = StringIO(image) image = PIL.Image.open(image) # When we create a new image during scaling we loose the format # information, so remember it here. format_ = image.format if format_ not in ('PNG', 'GIF'): # Always generate JPEG, except if format is PNG or GIF. format_ = 'JPEG' elif format_ == 'GIF': # GIF scaled looks better if we have 8-bit alpha and no palette format_ = 'PNG' icc_profile = image.info.get('icc_profile') image = scalePILImage(image, width, height, direction) # convert to simpler mode if possible colors = image.getcolors(maxcolors=256) if image.mode not in ('P', 'L') and colors: if format_ == 'JPEG': # check if it's all grey if all(rgb[0] == rgb[1] == rgb[2] for c, rgb in colors): image = image.convert('L') elif format_ == 'PNG': image = image.convert('P') if image.mode == 'RGBA' and format_ == 'JPEG': extrema = dict(zip(image.getbands(), image.getextrema())) if extrema.get('A') == (255, 255): # no alpha used, just change the mode, which causes the alpha band # to be dropped on save image.mode = "RGB" else: # switch to PNG, which supports alpha format_ = 'PNG' new_result = False if result is None: result = StringIO() new_result = True image.save(result, format_, quality=quality, optimize=True, progressive=True, icc_profile=icc_profile) if new_result: result = result.getvalue() else: result.seek(0) return result, format_, image.size
def scaleImage(image, width=None, height=None, direction='down', quality=88, result=None): """Scale the given image data to another size and return the result as a string or optionally write in to the file-like `result` object. The `image` parameter can either be the raw image data (ie a `str` instance) or an open file. The `quality` parameter can be used to set the quality of the resulting image scales. The return value is a tuple with the new image, the image format and a size-tuple. Optionally a file-like object can be given as the `result` parameter, in which the generated image scale will be stored. The `width`, `height`, `direction` parameters will be passed to :meth:`scalePILImage`, which performs the actual scaling. The generated image is a JPEG image, unless the original is a PNG or GIF image. This is needed to make sure alpha channel information is not lost, which JPEG does not support. """ if isinstance(image, str): image = StringIO(image) image = PIL.Image.open(image) # When we create a new image during scaling we loose the format # information, so remember it here. format_ = image.format if format_ not in ('PNG', 'GIF'): # Always generate JPEG, except if format is PNG or GIF. format_ = 'JPEG' elif format_ == 'GIF': # GIF scaled looks better if we have 8-bit alpha and no palette format_ = 'PNG' image = scalePILImage(image, width, height, direction) # convert to simpler mode if possible if image.mode not in ('P', 'L') and image.getcolors(maxcolors=256): if format_ == 'JPEG': image = image.convert('L') elif format_ == 'PNG': image = image.convert('P') new_result = False if result is None: result = StringIO() new_result = True image.save(result, format_, quality=quality, optimize=True, progressive=True) if new_result: result = result.getvalue() else: result.seek(0) return result, format_, image.size
def scaleImage(image, width=None, height=None, direction='down', quality=88, result=None): """Scale the given image data to another size and return the result as a string or optionally write in to the file-like `result` object. The `image` parameter can either be the raw image data (ie a `str` instance) or an open file. The `quality` parameter can be used to set the quality of the resulting image scales. The return value is a tuple with the new image, the image format and a size-tuple. Optionally a file-like object can be given as the `result` parameter, in which the generated image scale will be stored. The `width`, `height`, `direction` parameters will be passed to :meth:`scalePILImage`, which performs the actual scaling. The generated image is a JPEG image, unless the original is a PNG or GIF image. This is needed to make sure alpha channel information is not lost, which JPEG does not support. """ if isinstance(image, (bytes, str)): image = StringIO(image) image = PIL.Image.open(image) # When we create a new image during scaling we loose the format # information, so remember it here. format_ = image.format if format_ not in ('PNG', 'GIF'): # Always generate JPEG, except if format is PNG or GIF. format_ = 'JPEG' elif format_ == 'GIF': # GIF scaled looks better if we have 8-bit alpha and no palette format_ = 'PNG' icc_profile = image.info.get('icc_profile') image = scalePILImage(image, width, height, direction) # convert to simpler mode if possible colors = image.getcolors(maxcolors=256) if image.mode not in ('P', 'L') and colors: if format_ == 'JPEG': # check if it's all grey if all(rgb[0] == rgb[1] == rgb[2] for c, rgb in colors): image = image.convert('L') elif format_ == 'PNG': image = image.convert('P') if image.mode == 'RGBA' and format_ == 'JPEG': extrema = dict(zip(image.getbands(), image.getextrema())) if extrema.get('A') == (255, 255): # no alpha used, just change the mode, which causes the alpha band # to be dropped on save image.mode = "RGB" else: # switch to PNG, which supports alpha format_ = 'PNG' new_result = False if result is None: result = StringIO() new_result = True image.save( result, format_, quality=quality, optimize=True, progressive=True, icc_profile=icc_profile ) if new_result: result = result.getvalue() else: result.seek(0) return result, format_, image.size
def scaleImage(image, width=None, height=None, direction='down', quality=88, result=None): """Scale the given image data to another size and return the result as a string or optionally write in to the file-like `result` object. The `image` parameter can either be the raw image data (ie a `str` instance) or an open file. The `quality` parameter can be used to set the quality of the resulting image scales. The return value is a tuple with the new image, the image format and a size-tuple. Optionally a file-like object can be given as the `result` parameter, in which the generated image scale will be stored. The `width`, `height`, `direction` parameters will be passed to :meth:`scalePILImage`, which performs the actual scaling. The generated image is a JPEG image, unless the original is a PNG or GIF image. This is needed to make sure alpha channel information is not lost, which JPEG does not support. """ if isinstance(image, str): image = StringIO(image) image = PIL.Image.open(image) # When we create a new image during scaling we loose the format # information, so remember it here. format_ = image.format if format_ not in ('PNG', 'GIF'): # Always generate JPEG, except if format is PNG or GIF. format_ = 'JPEG' elif format_ == 'GIF': # GIF scaled looks better if we have 8-bit alpha and no palette format_ = 'PNG' image = scalePILImage(image, width, height, direction) # convert to simpler mode if possible if image.mode not in ('P', 'L') and image.getcolors(maxcolors=256): if format_ == 'JPEG': image = image.convert('L') elif format_ == 'PNG': image = image.convert('P') new_result = False if result is None: result = StringIO() new_result = True image.save( result, format_, quality=quality, optimize=True, progressive=True ) if new_result: result = result.getvalue() else: result.seek(0) return result, format_, image.size