/usr/lib/python3/dist-packages/glue/formats/img.py is in glue-sprite 0.13-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | import os
from PIL import Image as PILImage
from PIL import PngImagePlugin
from glue import __version__
from glue.helpers import round_up, cached_property
from .base import BaseFormat
class ImageFormat(BaseFormat):
build_per_ratio = True
extension = 'png'
@classmethod
def populate_argument_parser(cls, parser):
group = parser.add_argument_group("Sprite image options")
group.add_argument("--img",
dest="img_dir",
type=str,
default=os.environ.get('GLUE_IMG', True),
metavar='DIR',
help="Output directory for img files")
group.add_argument("--no-img",
dest="generate_image",
action="store_false",
default=os.environ.get('GLUE_GENERATE_IMG', True),
help="Don't genereate IMG files.")
group.add_argument("-c", "--crop",
dest="crop",
action='store_true',
default=os.environ.get('GLUE_CROP', False),
help="Crop images removing unnecessary transparent margins")
group.add_argument("-p", "--padding",
dest="padding",
type=str,
default=os.environ.get('GLUE_PADDING', '0'),
help="Force this padding in all images")
group.add_argument("--margin",
dest="margin",
type=str,
default=os.environ.get('GLUE_MARGIN', '0'),
help="Force this margin in all images")
group.add_argument("--png8",
action="store_true",
dest="png8",
default=os.environ.get('GLUE_PNG8', False),
help=("The output image format will be png8 "
"instead of png32"))
group.add_argument("--ratios",
dest="ratios",
type=str,
default=os.environ.get('GLUE_RATIOS', '1'),
help="Create sprites based on these ratios")
group.add_argument("--retina",
dest="ratios",
default=os.environ.get('GLUE_RETINA', False),
action='store_const',
const='2,1',
help="Shortcut for --ratios=2,1")
def output_filename(self, *args, **kwargs):
filename = super(ImageFormat, self).output_filename(*args, **kwargs)
if self.sprite.config['css_cachebuster_filename'] or self.sprite.config['css_cachebuster_only_sprites']:
return '{0}_{1}'.format(filename, self.sprite.hash)
return filename
def needs_rebuild(self):
for ratio in self.sprite.config['ratios']:
image_path = self.output_path(ratio)
try:
existing = PILImage.open(image_path)
assert existing.info['Software'] == 'glue-%s' % __version__
assert existing.info['Comment'] == self.sprite.hash
continue
except Exception:
return True
return False
@cached_property
def _raw_canvas(self):
# Create the sprite canvas
width, height = self.sprite.canvas_size
canvas = PILImage.new('RGBA', (width, height), (0, 0, 0, 0))
# Paste the images inside the canvas
for image in self.sprite.images:
canvas.paste(image.image,
(round_up(image.x + (image.padding[3] + image.margin[3]) * self.sprite.max_ratio),
round_up(image.y + (image.padding[0] + image.margin[0]) * self.sprite.max_ratio)))
meta = PngImagePlugin.PngInfo()
meta.add_text('Software', 'glue-%s' % __version__)
meta.add_text('Comment', self.sprite.hash)
# Customize how the png is going to be saved
kwargs = dict(optimize=False, pnginfo=meta)
if self.sprite.config['png8']:
# Get the alpha band
alpha = canvas.split()[-1]
canvas = canvas.convert('RGB'
).convert('P',
palette=PILImage.ADAPTIVE,
colors=255)
# Set all pixel values below 128 to 255, and the rest to 0
mask = PILImage.eval(alpha, lambda a: 255 if a <= 128 else 0)
# Paste the color of index 255 and use alpha as a mask
canvas.paste(255, mask)
kwargs.update({'transparency': 255})
return canvas, kwargs
def save(self, ratio):
width, height = self.sprite.canvas_size
canvas, kwargs = self._raw_canvas
# Loop all over the ratios and save one image for each one
for ratio in self.sprite.config['ratios']:
# Create the destination directory if required
if not os.path.exists(self.output_dir(ratio=ratio)):
os.makedirs(self.output_dir(ratio=ratio))
image_path = self.output_path(ratio=ratio)
# If this canvas isn't the biggest one scale it using the ratio
if self.sprite.max_ratio != ratio:
reduced_canvas = canvas.resize(
(round_up((width / self.sprite.max_ratio) * ratio),
round_up((height / self.sprite.max_ratio) * ratio)),
PILImage.ANTIALIAS)
reduced_canvas.save(image_path, **kwargs)
# TODO: Use Imagemagick if it's available
else:
canvas.save(image_path, **kwargs)
|