Beispiel #1
0
    def merge(self, image_opts, size=None, bbox=None, bbox_srs=None, coverage=None):
        """
        Merge the layers. If the format is not 'png' just return the last image.

        :param format: The image format for the result.
        :param size: The size for the merged output.
        :rtype: `ImageSource`
        """
        if not self.layers:
            return BlankImageSource(size=size, image_opts=image_opts, cacheable=True)
        if len(self.layers) == 1:
            layer_img, layer = self.layers[0]
            layer_opts = layer_img.image_opts
            if (((layer_opts and not layer_opts.transparent) or image_opts.transparent)
                and (not size or size == layer_img.size)
                and (not layer or not layer.coverage or not layer.coverage.clip)
                and not coverage):
                # layer is opaque, no need to make transparent or add bgcolor
                return layer_img

        if size is None:
            size = self.layers[0][0].size

        cacheable = self.cacheable
        result = create_image(size, image_opts)

        for layer_img, layer in self.layers:
            if not layer_img.cacheable:
                cacheable = False
            img = layer_img.as_image()
            layer_image_opts = layer_img.image_opts

            if layer and layer.coverage and layer.coverage.clip:
                img = mask_image(img, bbox, bbox_srs, layer.coverage)

            if (layer_image_opts and layer_image_opts.opacity is not None
                and layer_image_opts.opacity < 1.0):
                img = img.convert(result.mode)
                result = Image.blend(result, img, layer_image_opts.opacity)
            else:
                if img.mode == 'RGBA':
                    # paste w transparency mask from layer
                    result.paste(img, (0, 0), img)
                else:
                    result.paste(img, (0, 0))

        # apply global clip coverage
        if coverage:
            bg = create_image(size, image_opts)
            mask = mask_image(result, bbox, bbox_srs, coverage)
            bg.paste(result, (0, 0), mask)
            result = bg

        return ImageSource(result, size=size, image_opts=image_opts, cacheable=cacheable)
Beispiel #2
0
    def merge(self, image_opts, size=None, bbox=None, bbox_srs=None, coverage=None):
        """
        Merge the layers. If the format is not 'png' just return the last image.
        
        :param format: The image format for the result.
        :param size: The size for the merged output.
        :rtype: `ImageSource`
        """
        if not self.layers:
            return BlankImageSource(size=size, image_opts=image_opts, cacheable=True)
        if len(self.layers) == 1:
            layer_img, layer = self.layers[0]
            layer_opts = layer_img.image_opts
            if (((layer_opts and not layer_opts.transparent) or image_opts.transparent) 
                and (not size or size == layer_img.size)
                and (not layer or not layer.coverage or not layer.coverage.clip)):
                # layer is opaque, no need to make transparent or add bgcolor
                return layer_img
        
        if size is None:
            size = self.layers[0][0].size
        
        cacheable = self.cacheable
        result = create_image(size, image_opts)

        for layer_img, layer in self.layers:
            if not layer_img.cacheable:
                cacheable = False
            img = layer_img.as_image()
            layer_image_opts = layer_img.image_opts
            
            if layer and layer.coverage and layer.coverage.clip:
                img = mask_image(img, bbox, bbox_srs, layer.coverage)
                
            if (layer_image_opts and layer_image_opts.opacity is not None
                and layer_image_opts.opacity < 1.0):
                img = img.convert(result.mode)
                result = Image.blend(result, img, layer_image_opts.opacity)
            else:
                if img.mode == 'RGBA':
                    # paste w transparency mask from layer
                    result.paste(img, (0, 0), img)
                else:
                    result.paste(img, (0, 0))
        
        # apply global clip coverage
        if coverage:
            bg = create_image(size, image_opts)
            mask = mask_image(result, bbox, bbox_srs, coverage)
            bg.paste(result, (0, 0), mask)
            result = bg

        return ImageSource(result, size=size, image_opts=image_opts, cacheable=cacheable)
 def test_rgba_bgcolor_rgba_mode(self):
     img = create_image((100, 100),
                        ImageOptions(bgcolor=(200, 100, 0, 30),
                                     mode="RGBA"))
     assert img.size == (100, 100)
     assert img.mode == "RGBA"
     assert img.getcolors() == [(100 * 100, (200, 100, 0, 30))]
 def test_rgba_bgcolor_rgba_mode(self):
     img = create_image((100, 100),
                        ImageOptions(bgcolor=(200, 100, 0, 30),
                                     mode='RGBA'))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGBA')
     eq_(img.getcolors(), [(100 * 100, (200, 100, 0, 30))])
 def test_rgba_bgcolor_transparent(self):
     img = create_image((100, 100),
                        ImageOptions(bgcolor=(200, 100, 0, 30),
                                     transparent=True))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGBA')
     eq_(img.getcolors(), [(100 * 100, (200, 100, 0, 30))])
Beispiel #6
0
    def get_tile(self, crop_coord, tile_size):
        """
        Return the cropped tile.
        :param crop_coord: the upper left pixel coord to start
        :param tile_size: width and height of the new tile
        :rtype: `ImageSource`
        """
        minx, miny = crop_coord
        maxx = minx + tile_size[0]
        maxy = miny + tile_size[1]

        if (minx < 0 or miny < 0 or maxx > self.meta_img.size[0]
            or maxy > self.meta_img.size[1]):

            crop = self.meta_img.crop((
                max(minx, 0),
                max(miny, 0),
                min(maxx, self.meta_img.size[0]),
                min(maxy, self.meta_img.size[1])))
            result = create_image(tile_size, self.image_opts)
            result.paste(crop, (abs(min(minx, 0)), abs(min(miny, 0))))
            crop = result
        else:
            crop = self.meta_img.crop((minx, miny, maxx, maxy))
        return ImageSource(crop, size=tile_size, image_opts=self.image_opts)
Beispiel #7
0
def mask_image_source_from_coverage(img_source, bbox, bbox_srs, coverage, image_opts=None):
    if image_opts is None:
        image_opts = img_source.image_opts
    img = img_source.as_image()
    img = mask_image(img, bbox, bbox_srs, coverage)
    result = create_image(img.size, image_opts)
    result.paste(img, (0, 0), img)
    return ImageSource(result, image_opts=image_opts)
 def test_rgba_bgcolor_transparent(self):
     img = create_image(
         (100, 100),
         ImageOptions(bgcolor=(200, 100, 0, 30), transparent=True),
     )
     assert img.size == (100, 100)
     assert img.mode == "RGBA"
     assert img.getcolors() == [(100 * 100, (200, 100, 0, 30))]
Beispiel #9
0
def mask_image_source_from_coverage(img_source, bbox, bbox_srs, coverage,
    image_opts=None):
    if image_opts is None:
        image_opts = img_source.image_opts
    img = img_source.as_image()
    img = mask_image(img, bbox, bbox_srs, coverage)
    result = create_image(img.size, image_opts)
    result.paste(img, (0, 0), img)
    return ImageSource(result, image_opts=image_opts)
Beispiel #10
0
def SubImageSource(source, size, offset, image_opts, cacheable=True):
    """
    Create a new ImageSource with `size` and `image_opts` and
    place `source` image at `offset`.
    """
    # force new image to contain alpha channel
    new_image_opts = image_opts.copy()
    new_image_opts.transparent = True
    img = create_image(size, new_image_opts)

    if not hasattr(source, 'as_image'):
        source = ImageSource(source)
    subimg = source.as_image()
    img.paste(subimg, offset)
    return ImageSource(img, size=size, image_opts=image_opts, cacheable=cacheable)
Beispiel #11
0
def SubImageSource(source, size, offset, image_opts, cacheable=True):
    """
    Create a new ImageSource with `size` and `image_opts` and
    place `source` image at `offset`.
    """
    # force new image to contain alpha channel
    new_image_opts = image_opts.copy()
    new_image_opts.transparent = True
    img = create_image(size, new_image_opts)

    if not hasattr(source, 'as_image'):
        source = ImageSource(source)
    subimg = source.as_image()
    img.paste(subimg, offset)
    return ImageSource(img, size=size, image_opts=new_image_opts, cacheable=cacheable)
Beispiel #12
0
    def merge(self, ordered_tiles, image_opts):
        """
        Merge all tiles into one image.

        :param ordered_tiles: list of tiles, sorted row-wise (top to bottom)
        :rtype: `ImageSource`
        """
        if self.tile_grid == (1, 1):
            assert len(ordered_tiles) == 1
            if ordered_tiles[0] is not None:
                tile = ordered_tiles.pop()
                return tile
        src_size = self._src_size()

        result = create_image(src_size, image_opts)

        cacheable = True

        for i, source in enumerate(ordered_tiles):
            if source is None:
                continue
            try:
                if not source.cacheable:
                    cacheable = False
                tile = source.as_image()
                pos = self._tile_offset(i)
                tile.draft(image_opts.mode, self.tile_size)
                result.paste(tile, pos)
                source.close_buffers()
            except IOError as e:
                if e.errno is None:  # PIL error
                    log.warning(
                        'unable to load tile %s, removing it (reason was: %s)'
                        % (source, str(e)))
                    if getattr(source, 'filename'):
                        if os.path.exists(source.filename):
                            os.remove(source.filename)
                else:
                    raise
        return ImageSource(result,
                           size=src_size,
                           image_opts=image_opts,
                           cacheable=cacheable)
Beispiel #13
0
    def merge(self, ordered_tiles, image_opts):
        """
        Merge all tiles into one image.

        :param ordered_tiles: list of tiles, sorted row-wise (top to bottom)
        :rtype: `ImageSource`
        """
        if self.tile_grid == (1, 1):
            assert len(ordered_tiles) == 1
            if ordered_tiles[0] is not None:
                tile = ordered_tiles.pop()
                return tile
        src_size = self._src_size()

        result = create_image(src_size, image_opts)

        cacheable = True

        for i, source in enumerate(ordered_tiles):
            if source is None:
                continue
            try:
                if not source.cacheable:
                    cacheable = False
                tile = source.as_image()
                pos = self._tile_offset(i)
                tile.draft(image_opts.mode, self.tile_size)
                result.paste(tile, pos)
                source.close_buffers()
            except IOError as e:
                if e.errno is None: # PIL error
                    log.warn('unable to load tile %s, removing it (reason was: %s)'
                             % (source, str(e)))
                    if getattr(source, 'filename'):
                        if os.path.exists(source.filename):
                            os.remove(source.filename)
                else:
                    raise
        return ImageSource(result, size=src_size, image_opts=image_opts, cacheable=cacheable)
Beispiel #14
0
    def get_tile(self, crop_coord, tile_size):
        """
        Return the cropped tile.
        :param crop_coord: the upper left pixel coord to start
        :param tile_size: width and height of the new tile
        :rtype: `ImageSource`
        """
        minx, miny = crop_coord
        maxx = minx + tile_size[0]
        maxy = miny + tile_size[1]

        if (minx < 0 or miny < 0 or maxx > self.meta_img.size[0]
                or maxy > self.meta_img.size[1]):

            crop = self.meta_img.crop(
                (max(minx, 0), max(miny, 0), min(maxx, self.meta_img.size[0]),
                 min(maxy, self.meta_img.size[1])))
            result = create_image(tile_size, self.image_opts)
            result.paste(crop, (abs(min(minx, 0)), abs(min(miny, 0))))
            crop = result
        else:
            crop = self.meta_img.crop((minx, miny, maxx, maxy))
        return ImageSource(crop, size=tile_size, image_opts=self.image_opts)
 def test_transparent_rgb(self):
     img = create_image((100, 100),
                        ImageOptions(mode='RGB', transparent=True))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGB')
     eq_(img.getcolors(), [(100 * 100, (255, 255, 255))])
Beispiel #16
0
 def new_image(self, size):
     return create_image(size, self.image_opts)
 def test_rgba_bgcolor_rgba_mode(self):
     img = create_image((100, 100), ImageOptions(bgcolor=(200, 100, 0, 30), mode='RGBA'))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGBA')
     eq_(img.getcolors(), [(100*100, (200, 100, 0, 30))])
 def test_rgba_bgcolor_transparent(self):
     img = create_image((100, 100), ImageOptions(bgcolor=(200, 100, 0, 30), transparent=True))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGBA')
     eq_(img.getcolors(), [(100*100, (200, 100, 0, 30))])
 def test_bgcolor(self):
     img = create_image((100, 100), ImageOptions(bgcolor=(200, 100, 0)))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGB')
     eq_(img.getcolors(), [(100*100, (200, 100, 0))])
 def test_transparent_rgb(self):
     img = create_image((100, 100), ImageOptions(mode='RGB', transparent=True))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGB')
     eq_(img.getcolors(), [(100*100, (255, 255, 255))])
Beispiel #21
0
 def test_transparent_rgb(self):
     img = create_image((100, 100),
                        ImageOptions(mode="RGB", transparent=True))
     assert img.size == (100, 100)
     assert img.mode == "RGB"
     assert img.getcolors() == [(100 * 100, (255, 255, 255))]
 def test_default(self):
     img = create_image((100, 100))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGB')
     eq_(img.getcolors(), [(100 * 100, (255, 255, 255))])
Beispiel #23
0
 def new_image(self, size):
     return create_image(size, self.image_opts)
Beispiel #24
0
    def merge(self,
              image_opts,
              size=None,
              bbox=None,
              bbox_srs=None,
              coverage=None):
        """
        Merge the layers. If the format is not 'png' just return the last image.

        :param format: The image format for the result.
        :param size: The size for the merged output.
        :rtype: `ImageSource`
        """
        if not self.layers:
            return BlankImageSource(size=size,
                                    image_opts=image_opts,
                                    cacheable=True)
        if len(self.layers) == 1:
            layer_img, layer_coverage = self.layers[0]
            layer_opts = layer_img.image_opts
            if (((layer_opts and not layer_opts.transparent)
                 or image_opts.transparent)
                    and (not size or size == layer_img.size)
                    and (not layer_coverage or not layer_coverage.clip)
                    and not coverage):
                # layer is opaque, no need to make transparent or add bgcolor
                return layer_img

        if size is None:
            size = self.layers[0][0].size

        cacheable = self.cacheable
        result = create_image(size, image_opts)
        for layer_img, layer_coverage in self.layers:
            if not layer_img.cacheable:
                cacheable = False
            img = layer_img.as_image()
            layer_image_opts = layer_img.image_opts
            if layer_image_opts is None:
                opacity = None
            else:
                opacity = layer_image_opts.opacity

            if layer_coverage and layer_coverage.clip:
                img = mask_image(img, bbox, bbox_srs, layer_coverage)

            if result.mode != 'RGBA':
                merge_composite = False
            else:
                merge_composite = has_alpha_composite_support()

            if 'transparency' in img.info:
                # non-paletted PNGs can have a fixed transparency value
                # convert to RGBA to have full alpha
                img = img.convert('RGBA')

            if merge_composite:
                if opacity is not None and opacity < 1.0:
                    # fade-out img to add opacity value
                    img = img.convert("RGBA")
                    alpha = img.split()[3]
                    alpha = ImageChops.multiply(
                        alpha, ImageChops.constant(alpha, int(255 * opacity)))
                    img.putalpha(alpha)
                if img.mode in ('RGBA', 'P'):
                    # assume paletted images have transparency
                    if img.mode == 'P':
                        img = img.convert('RGBA')
                    result = Image.alpha_composite(result, img)
                else:
                    result.paste(img, (0, 0))
            else:
                if opacity is not None and opacity < 1.0:
                    img = img.convert(result.mode)
                    result = Image.blend(result, img, layer_image_opts.opacity)
                elif img.mode in ('RGBA', 'P'):
                    # assume paletted images have transparency
                    if img.mode == 'P':
                        img = img.convert('RGBA')
                    # paste w transparency mask from layer
                    result.paste(img, (0, 0), img)
                else:
                    result.paste(img, (0, 0))

        # apply global clip coverage
        if coverage:
            bg = create_image(size, image_opts)
            mask = mask_image(result, bbox, bbox_srs, coverage)
            bg.paste(result, (0, 0), mask)
            result = bg

        return ImageSource(result,
                           size=size,
                           image_opts=image_opts,
                           cacheable=cacheable)
Beispiel #25
0
 def as_image(self):
     if not self._img:
         self._img = create_image(self.size, self.image_opts)
     return self._img
Beispiel #26
0
 def test_merge_composite(self):
     img = create_image((100, 100), ImageOptions(merge='composite'))
     eq_(img.mode, 'RGBA')
Beispiel #27
0
 def test_default(self):
     img = create_image((100, 100))
     assert img.size == (100, 100)
     assert img.mode == "RGB"
     assert img.getcolors() == [(100 * 100, (255, 255, 255))]
 def test_bgcolor(self):
     img = create_image((100, 100), ImageOptions(bgcolor=(200, 100, 0)))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGB')
     eq_(img.getcolors(), [(100 * 100, (200, 100, 0))])
Beispiel #29
0
 def as_image(self):
     if not self._img:
         self._img = create_image(self.size, self.image_opts)
     return self._img
 def test_default(self):
     img = create_image((100, 100))
     eq_(img.size, (100, 100))
     eq_(img.mode, 'RGB')
     eq_(img.getcolors(), [(100*100, (255, 255, 255))])
Beispiel #31
0
    def merge(self, image_opts, size=None, bbox=None, bbox_srs=None, coverage=None):
        """
        Merge the layers. If the format is not 'png' just return the last image.

        :param format: The image format for the result.
        :param size: The size for the merged output.
        :rtype: `ImageSource`
        """
        if not self.layers:
            return BlankImageSource(size=size, image_opts=image_opts, cacheable=True)
        if len(self.layers) == 1:
            layer_img, layer = self.layers[0]
            layer_opts = layer_img.image_opts
            if (((layer_opts and not layer_opts.transparent) or image_opts.transparent)
                and (not size or size == layer_img.size)
                and (not layer or not layer.coverage or not layer.coverage.clip)
                and not coverage):
                # layer is opaque, no need to make transparent or add bgcolor
                return layer_img

        if size is None:
            size = self.layers[0][0].size

        cacheable = self.cacheable
        result = create_image(size, image_opts)
        for layer_img, layer in self.layers:
            if not layer_img.cacheable:
                cacheable = False
            img = layer_img.as_image()
            layer_image_opts = layer_img.image_opts
            if layer_image_opts is None:
                opacity = None
            else:
                opacity = layer_image_opts.opacity

            if layer and layer.coverage and layer.coverage.clip:
                img = mask_image(img, bbox, bbox_srs, layer.coverage)

            if result.mode != 'RGBA':
                merge_composite = False
            else:
                merge_composite = has_alpha_composite_support()

            if merge_composite:
                if opacity is not None and opacity < 1.0:
                    # fade-out img to add opacity value
                    img = img.convert("RGBA")
                    alpha = img.split()[3]
                    alpha = ImageChops.multiply(
                        alpha,
                        ImageChops.constant(alpha, int(255 * opacity))
                    )
                    img.putalpha(alpha)
                if img.mode in ('RGBA', 'P'):
                    # assume paletted images have transparency
                    if img.mode == 'P':
                        img = img.convert('RGBA')
                    result = Image.alpha_composite(result, img)
                else:
                    result.paste(img, (0, 0))
            else:
                if opacity is not None and opacity < 1.0:
                    img = img.convert(result.mode)
                    result = Image.blend(result, img, layer_image_opts.opacity)
                elif img.mode in ('RGBA', 'P'):
                    # assume paletted images have transparency
                    if img.mode == 'P':
                        img = img.convert('RGBA')
                    # paste w transparency mask from layer
                    result.paste(img, (0, 0), img)
                else:
                    result.paste(img, (0, 0))

        # apply global clip coverage
        if coverage:
            bg = create_image(size, image_opts)
            mask = mask_image(result, bbox, bbox_srs, coverage)
            bg.paste(result, (0, 0), mask)
            result = bg

        return ImageSource(result, size=size, image_opts=image_opts, cacheable=cacheable)
Beispiel #32
0
 def test_bgcolor(self):
     img = create_image((100, 100), ImageOptions(bgcolor=(200, 100, 0)))
     assert img.size == (100, 100)
     assert img.mode == "RGB"
     assert img.getcolors() == [(100 * 100, (200, 100, 0))]