def process(self, img): # Convert bgcolor string to RGB value. background_color = ImageColor.getrgb(self.background_color) # Handle palleted images. img = img.convert('RGBA') # Copy orignial image and flip the orientation. reflection = img.copy().transpose(Image.FLIP_TOP_BOTTOM) # Create a new image filled with the bgcolor the same size. background = Image.new("RGBA", img.size, background_color) # Calculate our alpha mask. start = int(255 - (255 * self.opacity)) # The start of our gradient. steps = int(255 * self.size) # The number of intermedite values. increment = (255 - start) / float(steps) mask = Image.new('L', (1, 255)) for y in range(255): if y < steps: val = int(y * increment + start) else: val = 255 mask.putpixel((0, y), val) alpha_mask = mask.resize(img.size) # Merge the reflection onto our background color using the alpha mask. reflection = Image.composite(background, reflection, alpha_mask) # Crop the reflection. reflection_height = int(img.size[1] * self.size) reflection = reflection.crop((0, 0, img.size[0], reflection_height)) # Create new image sized to hold both the original image and # the reflection. composite = Image.new("RGBA", (img.size[0], img.size[1] + reflection_height), background_color) # Paste the orignal image and the reflection into the composite image. composite.paste(img, (0, 0)) composite.paste(reflection, (0, img.size[1])) # Return the image complete with reflection effect. return composite
def process(cls, image, fmt, obj=None): """Adds a watermark to an image.""" if image.mode != 'RGBA': image = image.convert('RGBA') pink = (255, 94, 200) white = (255, 255, 255) im_width, im_height = image.size copyright = "Copyright \xa9 by the Artist and Burning Man" overlay = Image.new('RGBA', image.size, (0,0,0,0)) draw = ImageDraw.Draw(overlay) draw.rectangle((0, im_height - 20, im_width, im_height), fill=(0,0,0,90)) draw.text((10, im_height - 15), copyright, fill=(255,255,255,90)) newimage = Image.new('RGB', (im_width, im_height + 50), white) draw2 = ImageDraw.Draw(newimage) draw2.text((10, im_height + 5), "\xa9 All images are copyright in their respective year, by " "both the ", fill=pink) draw2.text((10, im_height + 15), "photographer and Burning Man. For publication or other use ", fill=pink) draw2.text((10, im_height + 25), "requests, contact the photographer at the email provided and ", fill=pink) draw2.text((10, im_height + 35), "[email protected] for written permission.", fill=pink) comp = Image.composite(overlay, image, overlay) newimage.paste(comp, (0,0)) return newimage, fmt
def get_default_photo(self): try: return Photo.objects.filter(user_default=True)[0] except IndexError: user_fallback = "%s/photos/%s" % (settings.MEDIA_ROOT, "img_user_fallback.png") try: fp = open(user_fallback, "r") image = Image.open(fp) image.verify() photo = Photo(user_default=True) photo.save() Photo.objects.filter(pk=photo.pk).update(image="photos/img_user_fallback.png") photo = Photo.objects.get(pk=photo.pk) fp.close() return photo except: user_fallback = "%s/images/%s" % (settings.GLOBALS_STATIC_ROOT, "img_user_fallback.png") fp = open(user_fallback, "r") image = Image.open(fp) image.verify() fp2 = open(user_fallback, "r") target_file = File(fp2) name = "img_user_fallback.png" photo = Photo(user_default=True) photo.image.save(name, target_file, save=True) fp.close() fp2.close() return photo
def process(self, image): mask = Image.open(os.path.join(settings.STATIC_ROOT, 'img/avatar-mask.png')) layer = Image.new('RGBA', image.size) layer.paste(mask) newImage = Image.composite(layer, image, layer) return newImage
def process(self, img): # get watermark wm = self._get_watermark() wm_size = wm.size # print('wm', wm) # print('wm.mode', wm.mode) # from PIL.PngImagePlugin import PngImageFile # from PIL.JpegImagePlugin import JpegImageFile if self.scale: if isinstance(self.scale, (int, float)) and self.scale != 1: # L&X # wm_size[0] *= self.scale # wm_size[1] *= self.scale wm_size = (wm_size[0] * self.scale, wm_size[1] * self.scale) wm = wm.scale(wm_size) elif self.scale == True: # from .resize import ResizeToFit from imagekit.processors import ResizeToFit wm = ResizeToFit(width=img.size[0], height=img.size[1], upscale=True).process(wm) wm_size = wm.size # prepare image for overlaying (ensure alpha channel) if img.mode != 'RGBA': img = img.convert('RGBA') # create a layer to place the watermark layer = Image.new('RGBA', img.size, (0, 0, 0, 0)) coords = _process_coords(img.size, wm_size, self.position) print('L&X', 'wm', wm) print('L&X', 'wm.size', wm.size) print('L&X', 'coords', coords) coords = (int(coords[0]), int(coords[1])) if self.repeat: sx = coords[0] % wm_size[0] - wm_size[0] sy = coords[1] % wm_size[1] - wm_size[1] for x in range(sx, img.size[0], wm_size[0]): for y in range(sy, img.size[1], wm_size[1]): layer.paste(wm, (x, y)) else: layer.paste(wm, coords) if self.opacity < 1: alpha = layer.split()[3] alpha = ImageEnhance.Brightness(alpha).enhance(self.opacity) layer.putalpha(alpha) # merge watermark layer img = Image.composite(layer, img, layer) return img
def set_watermark(image): watermark = Archive.objects.get(id=51) watermark = Image.open(watermark.archive) image = Image.open(image) scaled = ImageWatermark(watermark, position=("center", "center"), scale=True, opacity=1) img_scaled = scaled.process(image) return img_scaled
def get_watermark(self): # open the image despite the format that the user provided for it if self.watermark: return self.watermark if self.watermark_image: return self.watermark_image if self.watermark_file: return Image.open(self.watermark_file) if self.watermark_path: return Image.open(self.watermark_path)
def setUp(self): # create a test image using tempfile and PIL self.tmp = tempfile.TemporaryFile() Image.new('RGB', (800, 600)).save(self.tmp, 'JPEG') self.tmp.seek(0) self.p = TestPhoto() self.p.image.save(os.path.basename('test.jpg'), ContentFile(self.tmp.read())) self.p.save() # destroy temp file self.tmp.close()
def _preinit_pil(): """Loads the standard PIL file format drivers. Returns True if ``preinit()`` was called (and there's a potential that more drivers were loaded) or False if there is no possibility that new drivers were loaded. """ global _pil_init if _pil_init < 1: Image.preinit() _pil_init = 1 return True return False
def process_zipfile(self): if os.path.isfile(self.zip_file.path): # TODO: implement try-except here zip = zipfile.ZipFile(self.zip_file.path) bad_file = zip.testzip() if bad_file: raise Exception('"%s" in the .zip archive is corrupt.' % bad_file) count = 1 if self.gallery: gallery = self.gallery else: gallery = Gallery.objects.create(title=self.title, title_slug=slugify(self.title), description=self.description, is_public=self.is_public) from cStringIO import StringIO for filename in zip.namelist(): if filename.startswith('__'): # do not process meta files continue data = zip.read(filename) if len(data): try: # the following is taken from django.newforms.fields.ImageField: # load() is the only method that can spot a truncated JPEG, # but it cannot be called sanely after verify() trial_image = Image.open(StringIO(data)) trial_image.load() # verify() is the only method that can spot a corrupt PNG, # but it must be called immediately after the constructor trial_image = Image.open(StringIO(data)) trial_image.verify() except Exception, e: # if a "bad" file is found we just skip it. raise e continue while 1: title = ' '.join([self.title, str(count)]) slug = slugify(title) try: p = Photo.objects.get(title_slug=slug) except Photo.DoesNotExist: photo = Photo(title=title, title_slug=slug, caption=self.caption, is_public=self.is_public) photo.image.save(filename, ContentFile(data)) gallery.photos.add(photo) count = count + 1 break count = count + 1 zip.close() return gallery
def generate_lenna(): """ See also: http://en.wikipedia.org/wiki/Lenna http://sipi.usc.edu/database/database.php?volume=misc&image=12 """ tmp = tempfile.TemporaryFile() lennapath = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'assets', 'lenna-800x600-white-border.jpg') with open(lennapath, "r+b") as lennafile: Image.open(lennafile).save(tmp, 'JPEG') tmp.seek(0) return tmp
def detect_border_color(img): mask = Image.new("1", img.size, 1) w, h = img.size[0] - 2, img.size[1] - 2 if w > 0 and h > 0: draw = ImageDraw.Draw(mask) draw.rectangle([1, 1, w, h], 0) return ImageStat.Stat(img.convert("RGBA").histogram(mask)).median
def process(self, img): # get watermark wm = self._get_watermark() wm_size = wm.size if self.scale: if isinstance(self.scale, (int, float)) and self.scale != 1: wm_size[0] *= self.scale wm_size[1] *= self.scale wm = wm.scale(wm_size) elif self.scale == True: from imagekit.processors import ResizeToFit wm = ResizeToFit(width=img.size[0], height=img.size[1], upscale=True).process(wm) wm_size = wm.size # prepare image for overlaying (ensure alpha channel) if img.mode != 'RGBA': img = img.convert('RGBA') # create a layer to place the watermark layer = Image.new('RGBA', img.size, (0, 0, 0, 0)) coords = _process_coords(img.size, wm_size, self.position) if self.repeat: sx = coords[0] % wm_size[0] - wm_size[0] sy = coords[1] % wm_size[1] - wm_size[1] for x in range(sx, img.size[0], wm_size[0]): for y in range(sy, img.size[1], wm_size[1]): layer.paste(wm, (x, y)) else: layer.paste(wm, coords) if self.opacity < 1: alpha = layer.split()[3] alpha = ImageEnhance.Brightness(alpha).enhance(self.opacity) layer.putalpha(alpha) # merge watermark layer img = Image.composite(layer, img, layer) return img
def process(self, img): # get watermark wm = self._get_watermark() wm_size = wm.size if self.scale: if isinstance(self.scale, (int, float)) and self.scale != 1: wm_size[0] *= self.scale wm_size[1] *= self.scale wm = wm.scale(wm_size) elif self.scale == True: wm = ResizeToFit(width=img.size[0], height=img.size[1], upscale=True).process(wm) wm_size = wm.size # prepare image for overlaying (ensure alpha channel) if img.mode != 'RGBA': img = img.convert('RGBA') # create a layer to place the watermark layer = Image.new('RGBA', img.size, (0,0,0,0)) coords = _process_coords(img.size, wm_size, self.position) if self.repeat: sx = coords[0] % wm_size[0] - wm_size[0] sy = coords[1] % wm_size[1] - wm_size[1] for x in range(sx, img.size[0], wm_size[0]): for y in range(sy, img.size[1], wm_size[1]): layer.paste(wm, (x,y)) else: layer.paste(wm, coords) if self.opacity < 1: alpha = layer.split()[3] alpha = ImageEnhance.Brightness(alpha).enhance(self.opacity) layer.putalpha(alpha) # merge watermark layer img = Image.composite(layer, img, layer) return img
def resized(self, h=0, w=0, footer=True, extended=True, crop=False, upscale=False): """Get the image, resized and optionally watermarked""" fn = self.image.file.name suffix = ['_'] if not w: suffix.append('0') else: suffix.append(str(w)) suffix.append('x') if not h: suffix.append('0') else: suffix.append(str(h)) if footer or extended: suffix.append('-') if footer: suffix.append('w') if extended: suffix.append('e') suffix = ''.join(suffix) fn = get_scaled_media_path(self, filename=fn, suffix=suffix) if os.path.exists(fn): img = Image.open(fn) log.debug('returning cached image: %s', fn) else: img = Image.open(self.image.file.name) cw, ch = img.size if h == 0 and w == 0: h = ch w = cw if h != ch or w != cw: img = resize_image(img, h, w, crop=crop, upscale=upscale) if footer or extended: img = add_watermark(img, footer=footer, extended=extended) img.save(fn) log.debug('Created and cached new image: %s', fn) return img, fn
def process(self, img): # get watermark wm = Image.open(self.watermark_path) wm_size = wm.size # prepare image for overlaying (ensure alpha channel) if img.mode != 'RGBA': img = img.convert('RGBA') # create a layer to place the watermark layer = Image.new('RGBA', img.size, (0, 0, 0, 0)) coords = (img.size[0] - wm_size[0] - 20, img.size[1] - wm_size[1] - 20) layer.paste(wm, coords) img = Image.composite(layer, img, layer) return img
def process(cls, img, fmt, obj): if cls.width and cls.height: background_color = ImageColor.getrgb(cls.background_color) #FIXME : Image is not imported but it never raises exception so ... bg_picture = Image.new("RGB", (cls.width, cls.height), background_color) ## paste it bg_w, bg_h = bg_picture.size img_w, img_h = img.size coord_x, coord_y = (bg_w - img_w) / 2, (bg_h - img_h) / 2 bg_picture.paste(img, (coord_x, coord_y, coord_x + img_w, coord_y + img_h)) return bg_picture, fmt
def process(self, img_path): src_img = Image.open(img_path) wm = self._get_watermark() wm_size = list(wm.size) if self.scale: wm = ResizeToFit(src_img.size[0], src_img.size[1], True).process(wm) wm_size = wm.size # # prepare image for overlaying (ensure alpha channel) # if src_img.mode != 'RGBA': # src_img = src_img.convert('RGBA') # create a layer to place the watermark layer = Image.new('RGBA', src_img.size, (0, 0, 0, 0)) coordinates = self._process_coordinates(src_img.size, wm_size) if self.repeat: sx = coordinates[0] % wm_size[0] - wm_size[0] sy = coordinates[1] % wm_size[1] - wm_size[1] for x in range(sx, src_img.size[0], wm_size[0]): for y in range(sy, src_img.size[1], wm_size[1]): layer.paste(wm, (x, y)) else: layer.paste(wm, coordinates) if self.opacity < 1: alpha = layer.split()[3] alpha = ImageEnhance.Brightness(alpha).enhance(self.opacity) layer.putalpha(alpha) # merge watermark layer dst_img = Image.composite(layer, src_img, layer) os.remove(img_path) dst_img.save(img_path)
def __getattribute__(self, key): if key == "username": if not object.__getattribute__(self, "username") and self.id: self.username = self.user.username self.save() return self.username if key == "main_profile_pic": if not object.__getattribute__(self, "main_profile_pic"): try: default_photo = Photo.objects.filter(user_default=True)[0] return default_photo except IndexError: user_fallback = "%s/photos/%s" % (settings.MEDIA_ROOT, "img_user_fallback.png") try: fp = open(user_fallback, "r") image = Image.open(fp) image.verify() photo = Photo(user_default=True) photo.save() Photo.objects.filter(pk=photo.pk).update(image="photos/img_user_fallback.png") photo = Photo.objects.get(pk=photo.pk) fp.close() return photo except Exception, e: user_fallback = "%s/images/%s" % (settings.GLOBALS_STATIC_ROOT, "img_user_fallback.png") fp = open(user_fallback, "r") image = Image.open(fp) image.verify() fp2 = open(user_fallback, "r") target_file = File(fp2) name = "img_user_fallback.png" photo = Photo(user_default=True) photo.image.save(name, target_file, save=True) fp.close() fp2.close() return photo
def process(self, img): # Convert bgcolor string to RGB value. background_color = ImageColor.getrgb(self.background_color) # Handle palleted images. img = img.convert('RGB') # Copy orignial image and flip the orientation. reflection = img.copy().transpose(Image.FLIP_TOP_BOTTOM) # Create a new image filled with the bgcolor the same size. background = Image.new("RGB", img.size, background_color) # Calculate our alpha mask. start = int(255 - (255 * self.opacity)) # The start of our gradient. steps = int(255 * self.size) # The number of intermedite values. increment = (255 - start) / float(steps) mask = Image.new('L', (1, 255)) for y in range(255): if y < steps: val = int(y * increment + start) else: val = 255 mask.putpixel((0, y), val) alpha_mask = mask.resize(img.size) # Merge the reflection onto our background color using the alpha mask. reflection = Image.composite(background, reflection, alpha_mask) # Crop the reflection. reflection_height = int(img.size[1] * self.size) reflection = reflection.crop((0, 0, img.size[0], reflection_height)) # Create new image sized to hold both the original image and # the reflection. composite = Image.new("RGB", (img.size[0], img.size[1] + reflection_height), background_color) # Paste the orignal image and the reflection into the composite image. composite.paste(img, (0, 0)) composite.paste(reflection, (0, img.size[1])) # Return the image complete with reflection effect. return composite
def process(self, img): original_width, original_height = img.size if self.anchor: anchor = Anchor.get_tuple(self.anchor) trim_x, trim_y = self.width - original_width, \ self.height - original_height x = int(float(trim_x) * float(anchor[0])) y = int(float(trim_y) * float(anchor[1])) else: x, y = self.x, self.y new_img = Image.new('RGBA', (self.width, self.height), self.color) new_img.paste(img, (x, y)) return new_img
def process(self, img): original = img = img.convert('RGBA') for name in ['Color', 'Brightness', 'Contrast', 'Sharpness']: factor = getattr(self, name.lower()) if factor != 1.0: try: img = getattr(ImageEnhance, name)(img).enhance(factor) except ValueError: pass else: # PIL's Color and Contrast filters both convert the image # to L mode, losing transparency info, so we put it back. # See https://github.com/jdriscoll/django-imagekit/issues/64 if name in ('Color', 'Contrast'): img = Image.merge('RGBA', img.split()[:3] + original.split()[3:4]) return img
def process(self, img): original = img = img.convert('RGBA') for name in ['Color', 'Brightness', 'Contrast', 'Sharpness']: factor = getattr(self, name.lower()) if factor != 1.0: try: img = getattr(ImageEnhance, name)(img).enhance(factor) except ValueError: pass else: # PIL's Color and Contrast filters both convert the image # to L mode, losing transparency info, so we put it back. # See https://github.com/jdriscoll/django-imagekit/issues/64 if name in ('Color', 'Contrast'): img = Image.merge( 'RGBA', img.split()[:3] + original.split()[3:4]) return img
def process(self, img): source = img.convert("RGBA") border_color = self.color or tuple(detect_border_color(source)) bg = Image.new("RGBA", img.size, border_color) diff = ImageChops.difference(source, bg) if self.tolerance not in (0, 1): # If tolerance is zero, we've already done the job. A tolerance of # one would mean to trim EVERY color, and since that would result # in a zero-sized image, we just ignore it. if not 0 <= self.tolerance <= 1: raise ValueError( "%s is an invalid tolerance. Acceptable values" " are between 0 and 1 (inclusive)." % self.tolerance ) tmp = ImageChops.constant(diff, int(self.tolerance * 255)).convert("RGBA") diff = ImageChops.subtract(diff, tmp) bbox = diff.getbbox() if bbox: img = _crop(img, bbox, self.sides) return img
def create_user_profile(self, user): # Already exists, return if self.filter(user=user).exists(): return user.get_profile(), False up = self.create(user=user) anonymous = User.objects.get(username='******') if user.id == anonymous.id: user_fallback = '%s/images/%s' % (settings.GLOBALS_STATIC_ROOT, 'img_user_fallback.png') image = Image.open(user_fallback) image.verify() fp = open(user_fallback,'r') target_file = File(fp) name = 'img_user_fallback.png' up.image.save(name, target_file, save=True) fp.close() up.save() else: up.image = anonymous.get_profile().image up.save() return user.get_profile(), True
def get_picture_from_url(img_url, alter_name=None, update_photo=None, get_raw_file=False): """ By default, we use uuid_as_name because this can promise that in multiple threads situation no filename will be the same with each other. """ if img_url: try: path = settings.DOWNLOAD_DIRECTORY + str(uuid.uuid4()) filename = uuid.uuid4() content = urllib.urlretrieve(smart_str(img_url),path) content_type = content[1]['content-type'] if 'image' in content_type: filetype = '.' + content_type.split('/')[1] else: raise InvalidImageException # Verify picture image = Image.open(content[0]) image.verify() if get_raw_file: return open(content[0]) target_file = File(open(content[0])) name = '%s%s'%(filename, filetype) photo = update_photo if update_photo else Photo() photo.image.save(name, target_file, save=True) os.remove(content[0]) return photo except Exception, e: import traceback, sys etype, value, tb = sys.exc_info() print('%s\n' % ''.join(traceback.format_exception(etype, value, tb, 20))) return None
def create_image(): return Image.open(get_image_file())
def generate_image(self): tmp = tempfile.TemporaryFile() Image.new('RGB', (800, 600)).save(tmp, 'JPEG') tmp.seek(0) return tmp
def _get_watermark(self): watermark = Image.new("RGBA", (150, 150), (0, 0, 0, 0)) draw = ImageDraw.Draw(watermark, "RGBA") draw.text((0, 0), self.text, font=self._font, fill=self._text_color) return watermark
def add_watermark(image, footer=True, extended=True): if image.mode != 'RGBA': image = image.convert('RGBA') pink = (255, 94, 200) white = (255, 255, 255) im_width, im_height = image.size log.debug('size: %s', image.size) if im_height: fontsize = int(im_height/34) else: fontsize = int(im_width/34) if fontsize > 16: fontsize = 16 log.debug('font size=%i', fontsize) ttf = os.path.join(settings.MEDIA_ROOT, 'fonts', 'Tahoma.ttf') font = ImageFont.truetype(ttf, fontsize) overlay = Image.new('RGBA', image.size, (0,0,0,0)) if footer: copyright = "Copyright \xa9 by the Artist and Burning Man" draw = ImageDraw.Draw(overlay) draw.rectangle((0, im_height - fontsize - 6, im_width, im_height), fill=(0,0,0,90)) draw.text((10, im_height - fontsize - 4), copyright, fill=(255,255,255,90), font=font) if extended: newimage = Image.new('RGB', (im_width, im_height + 200), white) textheight = draw_word_wrap(newimage, EXTRA_COPY, 10, 5, max_width=im_width-10, fill=pink, font=font, height_only=True) h = im_height + textheight + 5 log.debug('new height: %s, textheight=%s', h, textheight) newimage = Image.new('RGB', (im_width, h), white) else: newimage = Image.new('RGB', (im_width, im_height)) if extended: #draw2 = ImageDraw.Draw(newimage) draw_word_wrap(newimage, EXTRA_COPY, 10, im_height + 5, max_width=im_width-10, fill=pink, font=font) # draw2.text((10, h), # "\xa9 All images are copyright in their respective year, by " # "both the ", # fill=pink, # font=font) # h += fontsize + 3 # draw2.text((10, h), # "photographer and Burning Man. For publication or other use ", # fill=pink, # font=font) # h += fontsize + 3 # draw2.text((10, h), # "requests, contact the photographer at the email provided and ", # fill=pink, # font=font) # h += fontsize + 3 # draw2.text((10, h), # "[email protected] for written permission.", # fill=pink, # font=font) comp = Image.composite(overlay, image, overlay) newimage.paste(comp, (0,0)) return newimage
def process(self, img): matte = False self.save_kwargs = {} if img.mode == 'RGBA': if self.format in RGBA_TRANSPARENCY_FORMATS: pass elif self.format in PALETTE_TRANSPARENCY_FORMATS: # If you're going from a format with alpha transparency to one # with palette transparency, transparency values will be # snapped: pixels that are more opaque than not will become # fully opaque; pixels that are more transparent than not will # become fully transparent. This will not produce a good-looking # result if your image contains varying levels of opacity; in # that case, you'll probably want to use a processor to matte # the image on a solid color. The reason we don't matte by # default is because not doing so allows processors to treat # RGBA-format images as a super-type of P-format images: if you # have an RGBA-format image with only a single transparent # color, and save it as a GIF, it will retain its transparency. # In other words, a P-format image converted to an # RGBA-formatted image by a processor and then saved as a # P-format image will give the expected results. alpha = img.split()[-1] mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0) img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255) img.paste(255, mask) self.save_kwargs['transparency'] = 255 else: # Simply converting an RGBA-format image to an RGB one creates a # gross result, so we matte the image on a white background. If # that's not what you want, that's fine: use a processor to deal # with the transparency however you want. This is simply a # sensible default that will always produce something that looks # good. Or at least, it will look better than just a straight # conversion. matte = True elif img.mode == 'P': if self.format in PALETTE_TRANSPARENCY_FORMATS: try: self.save_kwargs['transparency'] = img.info['transparency'] except KeyError: pass elif self.format in RGBA_TRANSPARENCY_FORMATS: # Currently PIL doesn't support any RGBA-mode formats that # aren't also P-mode formats, so this will never happen. img = img.convert('RGBA') else: matte = True else: img = img.convert('RGB') # GIFs are always going to be in palette mode, so we can do a little # optimization. Note that the RGBA sources also use adaptive # quantization (above). Images that are already in P mode don't need # any quantization because their colors are already limited. if self.format == 'GIF': img = img.convert('P', palette=Image.ADAPTIVE) if matte: img = img.convert('RGBA') bg = Image.new('RGBA', img.size, (255, 255, 255)) bg.paste(img, img) img = bg.convert('RGB') if self.format == 'JPEG': self.save_kwargs['optimize'] = True return img
def get_watermark(self): wm = Image.new("RGBA", self.font_size, (0,0,0,0)) draw = ImageDraw.Draw(wm, "RGBA") draw.text((0,0), self.text, font=self.font, fill=self.text_color) return wm
def process(self, img): matte = False self.save_kwargs = {} self.rgba_ = img.mode == 'RGBA' if self.rgba_: if self.format in RGBA_TRANSPARENCY_FORMATS: pass elif self.format in PALETTE_TRANSPARENCY_FORMATS: # If you're going from a format with alpha transparency to one # with palette transparency, transparency values will be # snapped: pixels that are more opaque than not will become # fully opaque; pixels that are more transparent than not will # become fully transparent. This will not produce a good-looking # result if your image contains varying levels of opacity; in # that case, you'll probably want to use a processor to matte # the image on a solid color. The reason we don't matte by # default is because not doing so allows processors to treat # RGBA-format images as a super-type of P-format images: if you # have an RGBA-format image with only a single transparent # color, and save it as a GIF, it will retain its transparency. # In other words, a P-format image converted to an # RGBA-formatted image by a processor and then saved as a # P-format image will give the expected results. alpha = img.split()[-1] mask = Image.eval(alpha, lambda a: 255 if a <= 128 else 0) img = img.convert('RGB').convert('P', palette=Image.ADAPTIVE, colors=255) img.paste(255, mask) self.save_kwargs['transparency'] = 255 else: # Simply converting an RGBA-format image to an RGB one creates a # gross result, so we matte the image on a white background. If # that's not what you want, that's fine: use a processor to deal # with the transparency however you want. This is simply a # sensible default that will always produce something that looks # good. Or at least, it will look better than just a straight # conversion. matte = True elif img.mode == 'P': if self.format in PALETTE_TRANSPARENCY_FORMATS: try: self.save_kwargs['transparency'] = img.info['transparency'] except KeyError: pass elif self.format in RGBA_TRANSPARENCY_FORMATS: # Currently PIL doesn't support any RGBA-mode formats that # aren't also P-mode formats, so this will never happen. img = img.convert('RGBA') else: matte = True else: img = img.convert('RGB') # GIFs are always going to be in palette mode, so we can do a little # optimization. Note that the RGBA sources also use adaptive # quantization (above). Images that are already in P mode don't need # any quantization because their colors are already limited. if self.format == 'GIF': img = img.convert('P', palette=Image.ADAPTIVE) if matte: img = img.convert('RGBA') bg = Image.new('RGBA', img.size, (255, 255, 255)) bg.paste(img, img) img = bg.convert('RGB') if self.format == 'JPEG': self.save_kwargs['optimize'] = True return img
def get_watermark(self): wm = Image.new("RGBA", self.font_size, (0, 0, 0, 0)) draw = ImageDraw.Draw(wm, "RGBA") draw.text((0, 0), self.text, font=self.font, fill=self.text_color) return wm
def open_image(target): target.seek(0) img = Image.open(target) img.copy = types.MethodType(_wrap_copy(img.copy), img, img.__class__) return img
def _get_watermark(self): return Image.open(self.image.path)
def get_registered_extensions(): Image.preinit() return Image.EXTENSION