Skip to content

Commit

Permalink
Require pixel arrays to be passed to TileManager.process_raw
Browse files Browse the repository at this point in the history
Before, encoded pixel buffers were being passed.
  • Loading branch information
jwiggins committed May 11, 2018
1 parent 8446aae commit 9d36815
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 42 deletions.
49 changes: 22 additions & 27 deletions mapping/enable/canvas.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from __future__ import print_function
from __future__ import division, print_function

import math
from io import BytesIO

from enable.api import Canvas, ColorTrait
from kiva.image import Image
from kiva.fonttools import str_to_font
from kiva.image import GraphicsContext
from kiva.constants import FILL
from traits.api import Int, Range, Instance, on_trait_change

Expand All @@ -25,36 +25,31 @@ class MappingCanvas(Canvas):
# FIXME This is a hack - remove when viewport is fixed
_zoom_level = Int(0)

_blank_tile = Instance(Image)
_blank_tile = Instance(GraphicsContext)

def __blank_tile_default(self):
import pkg_resources
from PIL import Image as PilImage
from PIL import ImageDraw, ImageFont

im = PilImage.new('RGB', (256, 256), (234, 224, 216))
gc = GraphicsContext((256, 256), pix_format='rgba32')
font = str_to_font('swiss 18')
gc.clear((0.9, 0.875, 0.85, 1.0))

text = 'Image not available'
try:
font_file = pkg_resources.resource_filename(
'mapping.enable', 'fonts/Verdana.ttf'
)
font = ImageFont.truetype(font_file, 18)
except IOError:
font = ImageFont.load_default()
size = font.getsize(text)
pos = (256-size[0])//2, (256-size[1])//2

draw = ImageDraw.Draw(im)
draw.text(pos, text, fill=(200, 200, 200), font=font)
del draw

tile = BytesIO()
im.save(tile, format='png')
return Image(BytesIO(tile.getvalue()))
with gc:
gc.set_font(font)
gc.set_stroke_color((0.75, 0.75, 0.75, 1.0))

width, height, _, _ = gc.get_full_text_extent(text)
pos = (256 - width) // 2, (256 - height) // 2
gc.translate_ctm(*pos)
gc.show_text(text)
return gc

def _tile_cache_changed(self, new):
new.process_raw = lambda d: Image(BytesIO(d))
fmt_map = {3: 'rgb24', 4: 'rgba32'}

def process(data):
return GraphicsContext(data, pix_format=fmt_map[data.shape[2]],
interpolation='nearest', bottom_up=True)
new.process_raw = process

@on_trait_change('tile_cache:tile_ready')
def _tile_ready(self, zoom_row_col):
Expand Down
Binary file removed mapping/enable/fonts/Verdana.ttf
Binary file not shown.
6 changes: 4 additions & 2 deletions mapping/enable/http_tile_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from .tile_manager import TileManager
from .cacheing_decorators import lru_cache
from .async_loader import AsyncLoader, AsyncRequest, get_global_async_loader
from .utils import img_data_to_img_array


@provides(ITileManager)
Expand Down Expand Up @@ -54,8 +55,9 @@ def _async_loader_default(self):
def _tile_received(self, tile_args, data):
zoom, row, col = tile_args['zoom'], tile_args['row'], tile_args['col']
try:
data = self.process_raw(data)
self.get_tile.replace(data, self, zoom, row, col)
img = img_data_to_img_array(data)
img = self.process_raw(img)
self.get_tile.replace(img, self, zoom, row, col)
self.tile_ready = (zoom, row, col)
except Exception:
# Failed to process tile
Expand Down
9 changes: 1 addition & 8 deletions mapping/enable/img_tile_manager.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
from __future__ import division

from io import BytesIO
import os
import os.path as op

import numpy as np
from PIL import Image

from traits.api import String, Tuple, provides

Expand Down Expand Up @@ -33,12 +31,7 @@ def get_tile(self, zoom, row, col):
tile_path = op.join(zoom_dir, '{}.{}.npy'.format(row, col))
if not op.exists(tile_path):
return None

tile = np.load(tile_path)
img = Image.fromarray(tile, mode='RGB')
data = BytesIO()
img.save(data, format='png')
return self.process_raw(data.getvalue())
return self.process_raw(np.load(tile_path))

def get_tile_size(self):
return 256
Expand Down
5 changes: 3 additions & 2 deletions mapping/enable/mbtile_manager.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@

from traits.api import Instance, Str, provides

from .i_tile_manager import ITileManager
from .tile_manager import TileManager
from .cacheing_decorators import lru_cache
from .mbtiles import MbtileSet
from .utils import img_data_to_img_array


@provides(ITileManager)
Expand All @@ -18,7 +18,8 @@ def get_tile(self, zoom, row, col):
if not data:
return None
else:
return self.process_raw(data)
img = img_data_to_img_array(data)
return self.process_raw(img)

def get_tile_size(self):
return 256
Expand Down
4 changes: 2 additions & 2 deletions mapping/enable/tests/test_canvas.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from unittest import TestCase

from kiva.image import Image
from kiva.image import GraphicsContext

from mapping.api import get_builtin_mbtiles_path
from mapping.enable.canvas import MappingCanvas
Expand All @@ -15,4 +15,4 @@ def setUp(self):
self.canvas = MappingCanvas(tile_cache=tile_layer)

def test__blank_tile(self):
self.assertIsInstance(self.canvas._blank_tile, Image)
self.assertIsInstance(self.canvas._blank_tile, GraphicsContext)
20 changes: 20 additions & 0 deletions mapping/enable/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from io import BytesIO

import numpy as np
from PIL import Image

from kiva.compat import piltostring

DEPTH_MAP = {'RGB': 3, 'RGBA': 4}


def img_data_to_img_array(data):
""" Convert a buffer of encoded image data to a numpy array of pixels.
"""
pil_img = Image.open(BytesIO(data))
if pil_img.mode not in ('RGB', 'RGBA'):
pil_img = pil_img.convert(mode='RGBA')

depth = DEPTH_MAP[pil_img.mode]
img = np.fromstring(piltostring(pil_img), np.uint8)
return np.resize(img, (pil_img.size[1], pil_img.size[0], depth))
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
include_package_data=True,
package_data={
'mapping': ['data/*'],
'mapping.enable': ['fonts/*'],
},
install_requires=__requires__,
license='BSD',
Expand Down

0 comments on commit 9d36815

Please # to comment.