def draw_text(image, text, horizontal_offset, vertical_offset, horizontal_justification, vertical_justification, size, color='#FFFFFF', orientation=None, font=None): """Draws text on an image.""" image = convert_safe_mode(image) if orientation: orientation = getattr(Image, orientation) draw = ImageDraw.Draw(image) if font.strip(): font = ImageFont.truetype(font, size) else: font = ImageFont.load_default() text = text.encode('ascii', 'replace') if orientation: font = ImageFont.TransposedFont(font, orientation) location = calculate_location( horizontal_offset, vertical_offset, horizontal_justification, vertical_justification, image.size, draw.textsize(text, font=font)) # draw draw.text(location, text, font=font, fill=color) # composite the watermark with the layer return image
def perspective(image, width, height, skew_x, skew_y, offset_x, offset_y, left, top, back_color, opacity, resample, crop, transpose): image = imtools.convert_safe_mode(image) if transpose == 'NONE': transpose = None else: transpose = getattr(Image, transpose) image = image.transpose(imtools.get_reverse_transposition(transpose)) if opacity != 100 or back_color != '#000000': image = image.convert('RGBA') if width != 0: width = 1 / width if height != 0: height = 1 / height offset_x = offset_x * width offset_y = offset_y * height skew_x = math.tan(r(skew_x)) skew_y = math.tan(r(skew_y)) matrix = (width, skew_x, offset_x, skew_y, height, offset_y, left, top) perspectived = image.transform(image.size, Image.PERSPECTIVE, matrix, resample) result = imtools.fill_background_color(perspectived, HTMLColorToRGBA(back_color, (255 * opacity) / 100)) if crop: result = imtools.auto_crop(result) if not (transpose is None): result = result.transpose(transpose) return result
def brightness(image, amount=50): """Adjust brightness from black to white - amount: -1(black) 0 (unchanged) 1(white) - repeat: how many times it should be repeated""" if amount == 0: return image image = imtools.convert_safe_mode(image) if amount < 0: #fade to black im = imtools.blend( image, Image.new(image.mode, image.size, 0), -amount / 100.0) else: #fade to white im = imtools.blend( image, Image.new(image.mode, image.size, ImageColor.getcolor('white', image.mode)), amount / 100.0) #fix image transparency mask if imtools.has_alpha(image): im.putalpha(imtools.get_alpha(image)) return im
def draw_text(image, text, horizontal_offset, vertical_offset, horizontal_justification, vertical_justification, size, color='#FFFFFF', orientation=None, font=None): """Draws text on an image.""" image = convert_safe_mode(image) if orientation: orientation = getattr(Image, orientation) draw = ImageDraw.Draw(image) if font.strip(): font = ImageFont.truetype(font, size) else: font = ImageFont.load_default() text = text.encode('ascii', 'replace') if orientation: font = ImageFont.TransposedFont(font, orientation) location = calculate_location(horizontal_offset, vertical_offset, horizontal_justification, vertical_justification, image.size, draw.textsize(text, font=font)) # draw draw.text(location, text, font=font, fill=color) # composite the watermark with the layer return image
def perspective(image, width, height, skew_x, skew_y, offset_x, offset_y, left, top, back_color, opacity, resample, crop, transpose): image = imtools.convert_safe_mode(image) if transpose == 'NONE': transpose = None else: transpose = getattr(Image, transpose) image = image.transpose(imtools.get_reverse_transposition(transpose)) if opacity != 100 or back_color != '#000000': image = image.convert('RGBA') if width != 0: width = 1 / width if height != 0: height = 1 / height offset_x = offset_x * width offset_y = offset_y * height skew_x = math.tan(r(skew_x)) skew_y = math.tan(r(skew_y)) matrix = (width, skew_x, offset_x, skew_y, height, offset_y, left, top) perspectived = image.transform(image.size, Image.PERSPECTIVE, matrix, resample) result = imtools.fill_background_color( perspectived, HTMLColorToRGBA(back_color, (255 * opacity) / 100)) if crop: result = imtools.auto_crop(result) if not (transpose is None): result = result.transpose(transpose) return result
def common(image, radius, amount=100): """Apply a filter - amount: 0-1""" image = imtools.convert_safe_mode(image) commoned = image.filter(ImageFilter.ModeFilter(radius)) if amount < 100: return imtools.blend(image, commoned, amount / 100.0) return commoned
def maximum(image, radius, amount=100): """Apply a filter - amount: 0-1""" image = imtools.convert_safe_mode(image) maximumed = image.filter(ImageFilter.MaxFilter(radius)) if amount < 100: return imtools.blend(image, maximumed, amount / 100.0) return maximumed
def median(image, radius, amount=100): """Apply a filter - amount: 0-1""" image = imtools.convert_safe_mode(image) medianed = image.filter(ImageFilter.MedianFilter(radius)) if amount < 100: return imtools.blend(image, medianed, amount / 100.0) return medianed
def invert(image, amount=100): image = imtools.convert_safe_mode(image) inverted = ImageChops.invert(image) if amount < 100: inverted = imtools.blend(image, inverted, amount / 100.0) if imtools.has_alpha(image): inverted.putalpha(imtools.get_alpha(image)) return inverted
def rnk(image, radius, rank=50, amount=100): """Apply a filter - amount: 0-1""" rank /= 100.0 r = int((radius * radius - 1) * rank) image = imtools.convert_safe_mode(image) ranked = image.filter(ImageFilter.RankFilter(radius, r)) if amount < 100: return imtools.blend(image, ranked, amount / 100) return ranked
def solarize(image, treshold, amount=100): """Apply a filter - amount: 0-1""" image = imtools.convert_safe_mode(image) solarized = image.convert('RGB') solarized = ImageOps.solarize(solarized, treshold) if imtools.has_alpha(image): imtools.put_alpha(solarized, imtools.get_alpha(image)) if amount < 100: return imtools.blend(image, solarized, amount / 100.0) return solarized
def posterize(image, bits, amount=100): """Apply a filter - amount: 0-1""" image = imtools.convert_safe_mode(image) posterized = imtools.remove_alpha(image) posterized = ImageOps.posterize(posterized, bits) if imtools.has_alpha(image): imtools.put_alpha(posterized, imtools.get_alpha(image)) if amount < 100: return imtools.blend(image, posterized, amount / 100.0) return posterized
def watermark(image, mark, horizontal_offset=None, vertical_offset=None, horizontal_justification=None, vertical_justification=None, orientation=None, method=None, opacity=100): """Adds a watermark to an image.""" if image.mode == 'P': image = convert_safe_mode(image) layer = generate_layer(image.size, mark, method, horizontal_offset, vertical_offset, horizontal_justification, vertical_justification, orientation, opacity) return Image.composite(layer, image, layer)
def draw_text(image, text, horizontal_offset, vertical_offset, horizontal_justification, vertical_justification, size, opacity, hallo, cache = {}, color='#FFFFFF', orientation=None, font=None): """Draws text on an image.""" image = convert_safe_mode(image) img_size = image.size mask_layer = Image.new('L',img_size, '#FFFFFF') color_layer = Image.new('RGB',img_size, color) draw = ImageDraw.Draw(mask_layer) if orientation: orientation = getattr(Image, orientation) if font.strip(): font = ImageFont.truetype(font, size) else: font = ImageFont.load_default() text = text.encode('ascii', 'replace') if orientation: font = ImageFont.TransposedFont(font, orientation) location = calculate_location( horizontal_offset, vertical_offset, horizontal_justification, vertical_justification, image.size, draw.textsize(text, font=font)) if hallo: x,y = img_size blurred_id = BLURED_ID % (x,y) if blurred_id in cache: hallo_mask_layer = cache[blurred_id] else: hallo_mask_layer = Image.new('L',img_size, '#FFFFFF') draw_hallo = ImageDraw.Draw(hallo_mask_layer) draw_hallo.text(location, text, font=font, fill=255-opacity) n = 0 while n < size/10: hallo_mask_layer = hallo_mask_layer.filter(ImageFilter.BLUR) draw_hallo.text(location, text, font=font, fill=255-opacity) n += 1 cache[blurred_id] = hallo_mask_layer hallo_color_layer = Image.new('RGB',img_size, color) hallo_color_layer = ImageChops.invert(hallo_color_layer) image = Image.composite(image,hallo_color_layer,hallo_mask_layer) draw.text(location, text, font=font, fill=255-opacity) # composite the watermark with the layer return Image.composite(image,color_layer,mask_layer)
def equalize(image, amount=100): image = imtools.convert_safe_mode(image) if imtools.has_alpha(image): equalized = imtools.remove_alpha(image) else: equalized = image equalized = ImageOps.equalize(equalized) if imtools.has_alpha(image): imtools.put_alpha(equalized, imtools.get_alpha(image)) if amount < 100: equalized = imtools.blend(image, equalized, amount / 100.0) return equalized
def autocontrast(image, amount=100.0, cutoff=0): """Apply a filter - amount: 0-1 - repeat: how many times it should be repeated""" image = imtools.convert_safe_mode(image) if imtools.has_transparency(image): im = imtools.remove_alpha(image) else: im = image contrasted = ImageOps.autocontrast(im, cutoff) if imtools.has_transparency(image): imtools.put_alpha(contrasted, imtools.get_alpha(image)) if amount < 100: return imtools.blend(image, contrasted, amount / 100.0) return contrasted
def tile(image, direction): if image.mode == 'P': image = convert_safe_mode(image) result = Image.new(image.mode, get_dimensions(image, direction)) paste(result, image, (0, 0)) if direction == BOTH: x_mirror(image, result) y_mirror(image, result) xy_mirror(image, result) if direction == HORIZONTAL: x_mirror(image, result) if direction == VERTICAL: y_mirror(image, result) return result
def effect(image, filter, amount=100, repeat=1): """Apply a filter - amount: 0-1 - repeat: how many times it should be repeated""" filter = getattr(ImageFilter, filter) image = imtools.convert_safe_mode(image) for i in range(repeat): filtered = image.filter(filter) if imtools.has_alpha(image) and \ filter in [ImageFilter.CONTOUR, ImageFilter.EMBOSS]: filtered.putalpha(imtools.get_alpha(image)) if amount < 100: image = imtools.blend(image, filtered, amount / 100.0) else: image = filtered return image
def brightness(image, amount=50): """Adjust brightness from black to white - amount: -1(black) 0 (unchanged) 1(white) - repeat: how many times it should be repeated""" if amount == 0: return image image = imtools.convert_safe_mode(image) if amount < 0: #fade to black im = imtools.blend(image, Image.new(image.mode, image.size, 0), -amount / 100.0) else: #fade to white im = imtools.blend( image, Image.new(image.mode, image.size, ImageColor.getcolor('white', image.mode)), amount / 100.0) #fix image transparency mask if imtools.has_alpha(image): im.putalpha(imtools.get_alpha(image)) return im
def make_grid(image, grid, col_line_width=0, row_line_width=0, line_color='#FFFFFF', line_opacity=0, old_size=None, scale=True): # Check if there is any work to do. if grid == (1, 1): return image # Because of layer support photo size can be different # from image layer size if old_size is None: old_size = image.size # Unpack grid cols, rows = grid # Scaling down? if scale: # Keep the same number of pixels in the result s = sqrt(cols * rows) old_size = tuple(map(lambda x: int(x / s), old_size)) # To scale down we need to make the image processing safe. image = imtools.convert_safe_mode(image)\ .resize(old_size, getattr(Image, 'ANTIALIAS')) #displacement dx, dy = old_size dx += col_line_width dy += row_line_width new_size = cols * dx - col_line_width, rows * dy - row_line_width # The main priority is that the new_canvas has the same mode as the image. # Palette images if image.mode == 'P': if 0 < line_opacity < 255: # transparent lines require RGBA image = imtools.convert(image, 'RGBA') else: if 'transparency' in image.info and line_opacity == 0: # Make line color transparent for images # with transparency. line_color_index = image.info['transparency'] palette = None else: line_color_index, palette = imtools.fit_color_in_palette( image, ImageColor.getrgb(line_color), ) if line_color_index != -1: new_canvas = Image.new('P', new_size, line_color_index) imtools.put_palette(new_canvas, image, palette) else: # Convert to non palette image (RGB or RGBA) image = imtools.convert_safe_mode(image) # Non palette images if image.mode != 'P': line_color = ImageColor.getcolor(line_color, image.mode) if imtools.has_alpha(image): # Make line color transparent for images # with an alpha channel. line_color = tuple(list(line_color)[:-1] + [line_opacity]) pass new_canvas = Image.new(image.mode, new_size, line_color) # Paste grid for x in range(cols): for y in range(rows): pos = (x * dx, y * dy) imtools.paste(new_canvas, image, pos, force=True) return new_canvas