Exemple #1
0
def scale_image_to_size(image=None,
                        bucket=None,
                        key=None,
                        uri=None,
                        max_pixels=None,
                        max_bytes=None):
    try:
        from PIL import Image
        if image:
            src_bytes = _image_byte_count(image)
        else:
            src_bytes = s3.get_object_size(bucket, key, uri)
            image = s3.read_pillow_image(bucket, key, uri)
        x, y = image.size
        src_pixels = x * y
        bytes_scalar = math.sqrt(max_bytes / src_bytes) if max_bytes else 1
        pixels_scalar = math.sqrt(max_pixels / src_pixels) if max_pixels else 1
        scalar = min(bytes_scalar, pixels_scalar)
        if scalar >= 1:
            return image, None
        else:
            new_x = int(scalar * x)
            new_y = int(scalar * y)
            new_image, scalar = image.resize((new_x, new_y),
                                             Image.BICUBIC), scalar
            if max_bytes and _image_byte_count(new_image) > max_bytes:
                return scale_image_to_size(image=image,
                                           max_pixels=max_pixels,
                                           max_bytes=int(max_bytes * 0.95))
            else:
                return new_image, scalar
    except ImportError as e:
        # Simply raise the ImportError to let the user know this requires Pillow to function
        raise e
Exemple #2
0
def render_boxes_from_objects(objects,
                              accessor,
                              image=None,
                              image_uri=None,
                              labels=None,
                              single_image=True,
                              color=None):
    # TODO: Avoid an unnecessary copy step when coming from uri
    if image_uri:
        image = s3.read_pillow_image(uri=image_uri)
    # Change palette mode images to RGB so that standard palette colors can be drawn on them
    if image.mode == 'P':
        image = image.convert(mode='RGB')
    else:
        image = image.copy()

    if isinstance(objects, collections.Mapping):
        annotation = accessor(objects)
        if labels:
            return render_boxes(annotation, image=image, image_uri=image_uri, color=color,
                                color_index=lambda idx, item: _find_label_index(item, labels))
        else:
            return render_boxes(annotation, image=image, image_uri=image_uri, color=color)
    elif single_image:
        for idx, obj in enumerate(objects):
            annotation = accessor(obj)
            if callable(color):
                image = render_boxes(annotation, image=image,
                                     color=lambda o_idx, e_idx, item: color(idx, e_idx, item),
                                     color_index=lambda i, item: idx)
            else:
                image = render_boxes(annotation, image=image,
                                     color_index=lambda i, item: idx)
        return image
    else:
        images = []
        for idx, obj in enumerate(objects):
            annotation = accessor(obj)
            if callable(color):
                images.append(render_boxes(annotation, image=image,
                                           color=lambda e_idx, item: color(idx, e_idx, item),
                                           color_index=lambda i, item: idx))
            else:
                images.append(render_boxes(annotation, image=image,
                                           color_index=lambda i, item: idx))
        return images
Exemple #3
0
def render_boxes(boxes,
                 image=None,
                 image_uri=None,
                 color=None,
                 width=None,
                 label_size=None,
                 label=None,
                 annotation_filter=None,
                 get_box=None,
                 color_index=None):
    if image_uri:
        image = s3.read_pillow_image(uri=image_uri)
    # Change palette mode images to RGB so that standard palette colors can be drawn on them
    if image.mode == 'P':
        image = image.convert(mode='RGB')
    else:
        image = image.copy()
    if color is None:
        color = get_color_list()
    width = round(image.width / 512) + 1 if width is None else width
    label_size = 20 if label_size is None else label_size

    try:
        from PIL import ImageDraw, ImageFont
        draw = ImageDraw.Draw(image)

        # TODO Find a better way to pull in fonts
        font = ImageFont.truetype("/usr/share/fonts/dejavu/DejaVuSans.ttf",
                                  size=label_size)

        for idx, item in enumerate(boxes):
            if annotation_filter is None or annotation_filter(idx, item):

                # Retrieve the box coordinates from the annotation
                if get_box:
                    item = get_box(idx, item)
                box = box_coordinates(item)

                # select a color to use with this box
                if isinstance(color, str):
                    box_color = color
                elif callable(color):
                    box_color = color(idx, item)
                elif color_index:
                    # TODO: Fix array out of bounds issue
                    box_color = color[color_index(idx, item)]
                else:
                    box_color = 'green'
                draw.rectangle(box, outline=box_color, width=width)
                if label:
                    if isinstance(label, str):
                        text = label
                    else:
                        text = label(idx, item)
                    size = draw.textsize(text, font=font, spacing=0)
                    draw.multiline_text((box[0] - size[0] - 4, box[1] + 4),
                                        text,
                                        fill=box_color,
                                        font=font,
                                        spacing=0,
                                        align='right')
        return image
    except ImportError as e:
        # Simply raise the ImportError to let the user know this requires Pillow to function
        raise e