Ejemplo n.º 1
0
def canvas_size(image, new_size, centering, background_color, opacity,
        old_size=None):
    #because of layer support photo size can be different from image layer size
    if old_size is None:
        old_size = image.size
    #check if image size has changed
    if old_size == new_size:
        return image
    #displacement
    dx = new_size[0] - old_size[0]
    dy = new_size[1] - old_size[1]
    #alignment
    x = int(centering[0] * dx / 100.0)
    y = int(centering[1] * dy / 100.0)
    #mode
    if image.mode in ['RGBA', 'LA', 'P']:
        if image.mode != 'RGBA':
            image = image.convert('RGBA')
        background_color = HTMLColorToRGBA(background_color, opacity)
    if image.mode in ['RGB', 'RGBA']:
        new_canvas = Image.new(image.mode, new_size, background_color)
    else:
        new_canvas = Image.new('RGB', new_size, background_color)
    if opacity > 0:
        imtools.paste(new_canvas, image, (x, y), mask=image)
    else:
        imtools.paste(new_canvas, image, (x, y), force=True)
    return new_canvas
Ejemplo n.º 2
0
def put_highlight(image, highlight, resample_highlight, opacity, cache=None):
    if cache is None:
        cache = {}
    resample_highlight = getattr(Image, resample_highlight)
    id = 'highlight_%s_w%d_h%d_o%d'\
        % (highlight, image.size[0], image.size[1], opacity)
    try:
        highlight = cache[id]
    except KeyError:
        highlight = open_image(highlight)\
            .convert('RGBA').resize(image.size, resample_highlight)
        if opacity < 100:
            #apply opacity
            highlight_alpha = imtools.get_alpha(highlight)
            opacity = (255 * opacity) / 100
            highlight.putalpha(ImageMath.eval("convert((a * o) / 255, 'L')",
                a=highlight_alpha, o=opacity))
        #store in cache
        cache[id] = highlight
    if not has_transparency(image):
        image = image.convert('RGBA')
    else:
        if has_transparency(image):
            image = image.convert('RGBA')
        alpha = imtools.get_alpha(image)
        highlight = highlight.copy()
        highlight_alpha = imtools.get_alpha(highlight)
        highlight.putalpha(ImageMath.eval("convert(min(a, b), 'L')",
            a=alpha, b=highlight_alpha))

    overlay = highlight.convert('RGB')
    paste(image, overlay, mask=highlight)
    return image
Ejemplo n.º 3
0
def canvas_size(image,
                new_size,
                centering,
                background_color,
                opacity,
                old_size=None):
    #because of layer support photo size can be different from image layer size
    if old_size is None:
        old_size = image.size
    #check if image size has changed
    if old_size == new_size:
        return image
    #displacement
    dx = new_size[0] - old_size[0]
    dy = new_size[1] - old_size[1]
    #alignment
    x = int(centering[0] * dx / 100.0)
    y = int(centering[1] * dy / 100.0)
    #mode
    if image.mode in ['RGBA', 'LA', 'P']:
        if image.mode != 'RGBA':
            image = image.convert('RGBA')
        background_color = HTMLColorToRGBA(background_color, opacity)
    if image.mode in ['RGB', 'RGBA']:
        new_canvas = Image.new(image.mode, new_size, background_color)
    else:
        new_canvas = Image.new('RGB', new_size, background_color)
    if opacity > 0:
        imtools.paste(new_canvas, image, (x, y), mask=image)
    else:
        imtools.paste(new_canvas, image, (x, y), force=True)
    return new_canvas
Ejemplo n.º 4
0
def border(image,
           method,
           border_width=0,
           left=0,
           right=0,
           top=0,
           bottom=0,
           color=0,
           opacity=100):
    """

    """
    #set up sizes, and make the target img
    if method == OPTIONS[0]:
        left, right, top, bottom = (border_width, ) * 4
    else:
        left, right, top, bottom = [x for x in left, right, top, bottom]

    #new image size attributes could get really messed up by negatives...
    new_width = sum([x for x in image.size[0], left, right if x >= 0])
    new_height = sum([x for x in image.size[1], top, bottom if x >= 0])

    # only need to do conversions when preserving transparency, or when
    # dealing with transparent overlays
    negative = [x for x in left, right, top, bottom if x < 0]
    if (negative and (opacity < 100)) or has_transparency(image):
        new_image = Image.new('RGBA', (new_width, new_height), color)
    else:
        new_image = Image.new('RGB', (new_width, new_height), color)

    # now for the masking component. The size of the mask needs to be the size
    # of the original image, and totally opaque. then we will have draw in
    # negative border values with an opacity scaled appropriately.
    # NOTE: the technique here is that rotating the image allows me to do
    # this with one simple draw operation, no need to add and subtract and
    # otherwise introduce geometry errors
    if negative:
        #draw transparent overlays
        mask = Image.new('L', image.size, 255)
        drawcolor = int(255 - (opacity / 100.0 * 255))
        for val in left, top, right, bottom:
            if val < 0:
                mask_draw = ImageDraw.Draw(mask)
                mask_draw.rectangle((0, 0, abs(val), max(mask.size)),
                                    drawcolor)
                del mask_draw
            mask = mask.rotate(90)
    else:
        mask = None

    # negative paste position values mess with the result.
    left = max(left, 0)
    top = max(top, 0)
    paste(new_image, image, (left, top), mask)

    return new_image
Ejemplo n.º 5
0
def create_rounded_rectangle(size=(600, 400),
                             cache={},
                             radius=100,
                             opacity=255,
                             pos=ROUNDED_POS):
    #rounded_rectangle
    im_x, im_y = size
    rounded_rectangle_id = ROUNDED_RECTANGLE_ID % (radius, opacity, size, pos)
    if rounded_rectangle_id in cache:
        return cache[rounded_rectangle_id]
    else:
        #cross
        cross_id = ROUNDED_RECTANGLE_ID % (radius, opacity, size, CROSS_POS)
        if cross_id in cache:
            cross = cache[cross_id]
        else:
            cross = cache[cross_id] = Image.new('L', size, 0)
            draw = ImageDraw.Draw(cross)
            draw.rectangle((radius, 0, im_x - radius, im_y), fill=opacity)
            draw.rectangle((0, radius, im_x, im_y - radius), fill=opacity)
        if pos == CROSS_POS:
            return cross
        #corner
        corner_id = CORNER_ID % (radius, opacity)
        if corner_id in cache:
            corner = cache[corner_id]
        else:
            corner = cache[corner_id] = create_corner(radius, opacity)
        #rounded rectangle
        rectangle = Image.new('L', (radius, radius), 255)
        rounded_rectangle = cross.copy()
        for index, angle in enumerate(pos):
            if angle == CROSS:
                continue
            if angle == ROUNDED:
                element = corner
            else:
                element = rectangle
            if index % 2:
                x = im_x - radius
                element = element.transpose(Image.FLIP_LEFT_RIGHT)
            else:
                x = 0
            if index < 2:
                y = 0
            else:
                y = im_y - radius
                element = element.transpose(Image.FLIP_TOP_BOTTOM)
            imtools.paste(rounded_rectangle, element, (x, y))
        cache[rounded_rectangle_id] = rounded_rectangle
        return rounded_rectangle
Ejemplo n.º 6
0
def round_image(image, cache={}, round_all=True, rounding_type=None,
        radius=100, opacity=255, pos=ROUNDED_POS, back_color='#FFFFFF'):
    if image.mode != 'RGBA':
        image = image.convert('RGBA')

    if round_all:
        pos = 4 * (rounding_type, )

    mask = create_rounded_rectangle(image.size, cache, radius, opacity, pos)

    imtools.paste(image, Image.new('RGB', image.size, back_color), (0, 0),
        ImageChops.invert(mask))
    image.putalpha(mask)
    return image
Ejemplo n.º 7
0
def put_contour(image,
                size=1,
                offset=0,
                contour_color=0,
                fill_color=0,
                opacity=100,
                include_image=True):
    if not has_transparency(image):
        return put_border(image, size, offset, contour_color, fill_color,
                          opacity, include_image)
    image = image.convert('RGBA')
    mask = imtools.get_alpha(image)

    w, h = image.size
    outer_mask = mask.resize(
        (w + 2 * (size + offset), h + 2 * (size + offset)), Image.ANTIALIAS)

    inner_mask = mask.resize((w + 2 * offset, h + 2 * offset), Image.ANTIALIAS)
    inner_mask = ImageOps.expand(inner_mask, border=size, fill=0)
    paste(outer_mask, (255 * opacity) / 100, mask=inner_mask)
    if include_image:
        image = ImageOps.expand(image, border=size + offset, fill=(0, 0, 0, 0))
        mask = ImageOps.expand(mask, border=size + offset, fill=0)
        paste(outer_mask, 255, mask=mask)

    contour = ImageOps.colorize(outer_mask, (255, 255, 255), contour_color)
    paste(contour, fill_color, mask=inner_mask)
    if include_image:
        paste(contour, image, mask=image)
    contour.putalpha(outer_mask)
    return contour
Ejemplo n.º 8
0
def put_contour(image, size=1, offset=0, contour_color=0, fill_color=0,
        opacity=100, include_image=True):
    if not has_transparency(image):
        return put_border(
                    image, size, offset, contour_color, fill_color,
                    opacity, include_image)
    image = image.convert('RGBA')
    mask = imtools.get_alpha(image)

    w, h = image.size
    outer_mask = mask.resize(
        (w + 2 * (size + offset), h + 2 * (size + offset)),
        Image.ANTIALIAS)

    inner_mask = mask.resize(
        (w + 2 * offset, h + 2 * offset),
        Image.ANTIALIAS)
    inner_mask = ImageOps.expand(inner_mask, border=size, fill=0)
    paste(outer_mask, (255 * opacity) / 100, mask=inner_mask)
    if include_image:
        image = ImageOps.expand(image, border=size + offset, fill=(0, 0, 0, 0))
        mask = ImageOps.expand(mask, border=size + offset, fill=0)
        paste(outer_mask, 255, mask=mask)

    contour = ImageOps.colorize(outer_mask, (255, 255, 255), contour_color)
    paste(contour, fill_color, mask=inner_mask)
    if include_image:
        paste(contour, image, mask=image)
    contour.putalpha(outer_mask)
    return contour
Ejemplo n.º 9
0
def create_rounded_rectangle(size=(600, 400), cache={}, radius=100,
        opacity=255, pos=ROUNDED_POS):
    #rounded_rectangle
    im_x, im_y = size
    rounded_rectangle_id = ROUNDED_RECTANGLE_ID % (radius, opacity, size, pos)
    if rounded_rectangle_id in cache:
        return cache[rounded_rectangle_id]
    else:
        #cross
        cross_id = ROUNDED_RECTANGLE_ID % (radius, opacity, size, CROSS_POS)
        if cross_id in cache:
            cross = cache[cross_id]
        else:
            cross = cache[cross_id] = Image.new('L', size, 0)
            draw = ImageDraw.Draw(cross)
            draw.rectangle((radius, 0, im_x - radius, im_y), fill=opacity)
            draw.rectangle((0, radius, im_x, im_y - radius), fill=opacity)
        if pos == CROSS_POS:
            return cross
        #corner
        corner_id = CORNER_ID % (radius, opacity)
        if corner_id in cache:
            corner = cache[corner_id]
        else:
            corner = cache[corner_id] = create_corner(radius, opacity)
        #rounded rectangle
        rectangle = Image.new('L', (radius, radius), 255)
        rounded_rectangle = cross.copy()
        for index, angle in enumerate(pos):
            if angle == CROSS:
                continue
            if angle == ROUNDED:
                element = corner
            else:
                element = rectangle
            if index % 2:
                x = im_x - radius
                element = element.transpose(Image.FLIP_LEFT_RIGHT)
            else:
                x = 0
            if index < 2:
                y = 0
            else:
                y = im_y - radius
                element = element.transpose(Image.FLIP_TOP_BOTTOM)
            imtools.paste(rounded_rectangle, element, (x, y))
        cache[rounded_rectangle_id] = rounded_rectangle
        return rounded_rectangle
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
def background(image, fill, mark, color,
        horizontal_offset=None, vertical_offset=None,
        horizontal_justification=None, vertical_justification=None,
        orientation=None, method=None, opacity=100):
    if not has_transparency(image):
        return image
    if image.mode == 'P':
        image = image.convert('RGBA')
    if fill == FILL_CHOICES[0]:
        opacity = (255 * opacity) / 100
        return fill_background_color(image, HTMLColorToRGBA(color,
            opacity))
    elif fill == FILL_CHOICES[1]:
        layer = generate_layer(image.size, mark, method,
                               horizontal_offset, vertical_offset,
                               horizontal_justification,
                               vertical_justification,
                               orientation, opacity)
        paste(layer, image, mask=image)
        return layer
Ejemplo n.º 13
0
def background(image,
               fill,
               mark,
               color,
               horizontal_offset=None,
               vertical_offset=None,
               horizontal_justification=None,
               vertical_justification=None,
               orientation=None,
               method=None,
               opacity=100):
    if not has_transparency(image):
        return image
    if image.mode == 'P':
        image = image.convert('RGBA')
    if fill == FILL_CHOICES[0]:
        opacity = (255 * opacity) / 100
        return fill_background_color(image, HTMLColorToRGBA(color, opacity))
    elif fill == FILL_CHOICES[1]:
        layer = generate_layer(image.size, mark, method, horizontal_offset,
                               vertical_offset, horizontal_justification,
                               vertical_justification, orientation, opacity)
        paste(layer, image, mask=image)
        return layer
Ejemplo n.º 14
0
def reflect(image,
            depth,
            opacity,
            background_color,
            background_opacity,
            scale_method,
            gap=0,
            scale_reflection=False,
            blur_reflection=False,
            cache=None):
    if has_transparency(image):
        image = image.convert('RGBA')
    else:
        image = image.convert('RGB')
    if cache is None:
        cache = {}
    opacity = (255 * opacity) / 100
    background_opacity = (255 * background_opacity) / 100
    scale_method = getattr(Image, scale_method)
    if background_opacity == 255:
        mode = 'RGB'
        color = background_color
    else:
        mode = 'RGBA'
        color = HTMLColorToRGBA(background_color, background_opacity)
    width, height = image.size
    depth = min(height, depth)
    #make reflection
    if has_alpha(image) and background_opacity > 0:
        reflection = Image.new(mode, image.size, color)
        paste(reflection, image, (0, 0), image)
    else:
        reflection = image
    reflection = reflection.transpose(Image.FLIP_TOP_BOTTOM)
    if scale_reflection:
        reflection = reflection.resize((width, depth), scale_method)
    else:
        reflection = reflection.crop((0, 0, width, depth))
    if blur_reflection:
        reflection = reflection.filter(ImageFilter.BLUR)
    mask = gradient_mask((width, depth), opacity, cache)
    #composite
    total_size = (width, height + gap + depth)
    total = Image.new(mode, total_size, color)
    paste(total, image, (0, 0), image)
    paste(total, reflection, (0, height + gap), mask)
    return total
Ejemplo n.º 15
0
def reflect(image, depth, opacity, background_color, background_opacity,
        scale_method, gap=0, scale_reflection=False,
        blur_reflection=False, cache=None):
    if has_transparency(image):
        image = image.convert('RGBA')
    else:
        image = image.convert('RGB')
    if cache is None:
        cache = {}
    opacity = (255 * opacity) / 100
    background_opacity = (255 * background_opacity) / 100
    scale_method = getattr(Image, scale_method)
    if background_opacity == 255:
        mode = 'RGB'
        color = background_color
    else:
        mode = 'RGBA'
        color = HTMLColorToRGBA(background_color, background_opacity)
    width, height = image.size
    depth = min(height, depth)
    #make reflection
    if has_alpha(image) and background_opacity > 0:
        reflection = Image.new(mode, image.size, color)
        paste(reflection, image, (0, 0), image)
    else:
        reflection = image
    reflection = reflection.transpose(Image.FLIP_TOP_BOTTOM)
    if scale_reflection:
        reflection = reflection.resize((width, depth), scale_method)
    else:
        reflection = reflection.crop((0, 0, width, depth))
    if blur_reflection:
        reflection = reflection.filter(ImageFilter.BLUR)
    mask = gradient_mask((width, depth), opacity, cache)
    #composite
    total_size = (width, height + gap + depth)
    total = Image.new(mode, total_size, color)
    paste(total, image, (0, 0), image)
    paste(total, reflection, (0, height + gap), mask)
    return total
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
def y_mirror(image, result):
    width, height = image.size
    paste(result, image.transpose(Image.FLIP_TOP_BOTTOM), (0, height))
Ejemplo n.º 18
0
def drop_shadow(image, horizontal_offset=5, vertical_offset=5,
        background_color=(255, 255, 255, 0), shadow_color=0x444444,
        border=8, shadow_blur=3, force_background_color=False, cache=None):
    """Add a gaussian blur drop shadow to an image.

    :param image: The image to overlay on top of the shadow.
    :param type: PIL Image
    :param offset:

        Offset of the shadow from the image as an (x,y) tuple.
        Can be positive or negative.

    :type offset: tuple of integers
    :param background_color: Background color behind the image.
    :param shadow_color: Shadow color (darkness).
    :param border:

        Width of the border around the image.  This must be wide
        enough to account for the blurring of the shadow.

    :param shadow_blur:

        Number of times to apply the filter.  More shadow_blur
        produce a more blurred shadow, but increase processing time.
    """
    if cache is None:
        cache = {}

    if has_transparency(image) and image.mode != 'RGBA':
        # Make sure 'LA' and 'P' with trasparency are handled
        image = image.convert('RGBA')

    #get info
    size = image.size
    mode = image.mode

    back = None

    #assert image is RGBA
    if mode != 'RGBA':
        if mode != 'RGB':
            image = image.convert('RGB')
            mode = 'RGB'
        #create cache id
        id = ''.join([str(x) for x in ['shadow_', size,
            horizontal_offset, vertical_offset, border, shadow_blur,
            background_color, shadow_color]])

        #look up in cache
        if id in cache:
            #retrieve from cache
            back, back_size = cache[id]

    if back is None:
        #size of backdrop
        back_size = (size[0] + abs(horizontal_offset) + 2 * border,
                        size[1] + abs(vertical_offset) + 2 * border)

        #create shadow mask
        if mode == 'RGBA':
            image_mask = imtools.get_alpha(image)
            shadow = Image.new('L', back_size, 0)
        else:
            image_mask = Image.new(mode, size, shadow_color)
            shadow = Image.new(mode, back_size, background_color)

        shadow_left = border + max(horizontal_offset, 0)
        shadow_top = border + max(vertical_offset, 0)
        paste(shadow, image_mask, (shadow_left, shadow_top,
                                shadow_left + size[0], shadow_top + size[1]))
        del image_mask  # free up memory

        #blur shadow mask

        #Apply the filter to blur the edges of the shadow.  Since a small
        #kernel is used, the filter must be applied repeatedly to get a decent
        #blur.
        n = 0
        while n < shadow_blur:
            shadow = shadow.filter(ImageFilter.BLUR)
            n += 1

        #create back
        if mode == 'RGBA':
            back = Image.new('RGBA', back_size, shadow_color)
            back.putalpha(shadow)
            del shadow  # free up memory
        else:
            back = shadow
            cache[id] = back, back_size

    #Paste the input image onto the shadow backdrop
    image_left = border - min(horizontal_offset, 0)
    image_top = border - min(vertical_offset, 0)
    if mode == 'RGBA':
        paste(back, image, (image_left, image_top), image)
        if force_background_color:
            mask = imtools.get_alpha(back)
            paste(back, Image.new('RGB', back.size, background_color),
                (0, 0), ImageChops.invert(mask))
            back.putalpha(mask)
    else:
        paste(back, image, (image_left, image_top))

    return back
Ejemplo n.º 19
0
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
Ejemplo n.º 20
0
def border(image, method, border_width=0, left=0, right=0, top=0, bottom=0,
        color=0, opacity=100):
    """

    """
    #set up sizes, and make the target img
    if method == OPTIONS[0]:
        left, right, top, bottom = (border_width, ) * 4
    else:
        left, right, top, bottom = [x for x in left, right, top, bottom]

    #new image size attributes could get really messed up by negatives...
    new_width = sum([x for x in image.size[0], left, right if x >= 0])
    new_height = sum([x for x in image.size[1], top, bottom if x >= 0])

    # only need to do conversions when preserving transparency, or when
    # dealing with transparent overlays
    negative = [x for x in left, right, top, bottom if x < 0]
    if (negative and (opacity < 100)) or has_transparency(image):
        new_image = Image.new('RGBA', (new_width, new_height), color)
    else:
        new_image = Image.new('RGB', (new_width, new_height), color)

    # now for the masking component. The size of the mask needs to be the size
    # of the original image, and totally opaque. then we will have draw in
    # negative border values with an opacity scaled appropriately.
    # NOTE: the technique here is that rotating the image allows me to do
    # this with one simple draw operation, no need to add and subtract and
    # otherwise introduce geometry errors
    if negative:
        #draw transparent overlays
        mask = Image.new('L', image.size, 255)
        drawcolor = int(255 - (opacity / 100.0 * 255))
        for val in left, top, right, bottom:
            if val < 0:
                mask_draw = ImageDraw.Draw(mask)
                mask_draw.rectangle((0, 0, abs(val), max(mask.size)),
                    drawcolor)
                del mask_draw
            mask = mask.rotate(90)
    else:
        mask = None

    # negative paste position values mess with the result.
    left = max(left, 0)
    top = max(top, 0)
    paste(new_image, image, (left, top), mask)

    return new_image

#---Phatch
CHOICES = ['-25', '-10', '-5', '-1', '0', '1', '5', '10', '25']


class Action(models.Action):
    label = _t('Border')
    author = 'Erich'
    email = '*****@*****.**'
    init = staticmethod(init)
    pil = staticmethod(border)
    version = '0.2'
    tags = [_t('filter')]
    __doc__ = _t('Draw border inside or outside')

    def interface(self, fields):
        fields[_t('Method')] = self.ChoiceField(OPTIONS[0], choices=OPTIONS)
        fields[_t('Border Width')] = self.PixelField('1px', choices=CHOICES)
        fields[_t('Left')] = self.PixelField('0px', choices=CHOICES)
        fields[_t('Right')] = self.PixelField('0px', choices=CHOICES)
        fields[_t('Top')] = self.PixelField('0px', choices=CHOICES)
        fields[_t('Bottom')] = self.PixelField('0px', choices=CHOICES)
        fields[_t('Color')] = self.ColorField('#000000')
        fields[_t('Opacity')] = self.SliderField(100, 1, 100)

    def values(self, info):
        #pixel fields
        width, height = info['size']
        # pass absolute reference for relative pixel values such as %
        return super(Action, self).values(info, pixel_fields={
            'Border Width': (width + height) / 2,
            'Left': width,
            'Right': width,
            'Top': height,
            'Bottom': height,
        })

    def get_relevant_field_labels(self):
        """If this method is present, Phatch will only show relevant
        fields.
        :returns: list of the field labels which are relevant
        :rtype: list of strings
        .. note::
            It is very important that the list of labels has EXACTLY
            the same order as defined in the interface method.
        """
        relevant = ['Method', 'Color', 'Opacity']
        if self.get_field_string('Method') == OPTIONS[0]:
            relevant.append('Border Width')
        else:
            relevant.extend(['Left', 'Right', 'Top', 'Bottom'])
        return relevant

    icon = \
'x\xda\x01x\x0b\x87\xf4\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\
Ejemplo n.º 21
0
def x_mirror(image, result):
    width, height = image.size
    paste(result, image.transpose(Image.FLIP_LEFT_RIGHT), (width, 0))
Ejemplo n.º 22
0
def x_mirror(image, result):
    width, height = image.size
    paste(result, image.transpose(Image.FLIP_LEFT_RIGHT), (width, 0))
Ejemplo n.º 23
0
def y_mirror(image, result):
    width, height = image.size
    paste(result, image.transpose(Image.FLIP_TOP_BOTTOM), (0, height))
Ejemplo n.º 24
0
def xy_mirror(image, result):
    paste(result, image.transpose(Image.ROTATE_180), image.size)
Ejemplo n.º 25
0
def xy_mirror(image, result):
    paste(result, image.transpose(Image.ROTATE_180), image.size)