Skip to content

Commit

Permalink
Make the test source banded images fancier.
Browse files Browse the repository at this point in the history
This makes it easier to see when multiple bands are composited.
  • Loading branch information
manthey committed Aug 17, 2022
1 parent 143446f commit a662621
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 42 deletions.
103 changes: 64 additions & 39 deletions sources/test/large_image_source_test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from large_image.constants import TILE_FORMAT_NUMPY, TILE_FORMAT_PIL, SourcePriority
from large_image.exceptions import TileSourceError
from large_image.tilesource import TileSource
from large_image.tilesource.utilities import _imageToNumpy
from large_image.tilesource.utilities import _imageToNumpy, _imageToPIL

try:
from importlib.metadata import PackageNotFoundError
Expand Down Expand Up @@ -178,37 +178,35 @@ def getInternalMetadata(self, **kwargs):
"""
return {'fractal': self.fractal, 'monochrome': self.monochrome}

@methodcache()
def getTile(self, x, y, z, *args, **kwargs):
frame = self._getFrame(**kwargs)
self._xyzInRange(x, y, z, frame, len(self._frames) if hasattr(self, '_frames') else None)

if not (self.minLevel <= z <= self.maxLevel):
raise TileSourceError('z layer does not exist')

xFraction = (x + 0.5) * self.tileWidth * 2 ** (self.levels - 1 - z) / self.sizeX
yFraction = (y + 0.5) * self.tileHeight * 2 ** (self.levels - 1 - z) / self.sizeY
fFraction = yFraction
if hasattr(self, '_frames'):
fFraction = float(frame) / (len(self._frames) - 1)

backgroundColor = colorsys.hsv_to_rgb(
h=xFraction,
s=(0.3 + (0.7 * fFraction)),
v=(0.3 + (0.7 * yFraction)),
)
rgbColor = tuple(int(val * 255) for val in backgroundColor)

def _tileImage(self, rgbColor, x, y, z, frame, band=None, bandnum=0):
image = Image.new(
mode='RGB',
size=(self.tileWidth, self.tileHeight),
color=(rgbColor if not self.fractal else (255, 255, 255))
)
imageDraw = ImageDraw.Draw(image)

if self.fractal:
self.fractalTile(image, x, y, 2 ** z, rgbColor)

bandtext = '\n' if band is not None else ''
if bandnum and band and band.lower() not in {
'r', 'red', 'g', 'green', 'b', 'blue', 'grey', 'gray', 'alpha'}:
bandtext += band
image = _imageToNumpy(image)[0].astype(float)
vstripe = numpy.array([
int(x / (self.tileWidth / bandnum / 2)) % 2
for x in range(self.tileWidth)])
hstripe = numpy.array([
int(y / (self.tileHeight / (bandnum % self.tileWidth) / 2)) % 2
if bandnum > self.tileWidth else 1 for y in range(self.tileHeight)])
simage = image.copy()
simage[hstripe == 0, :, :] /= 2
simage[:, vstripe == 0, :] /= 2
image = numpy.where(image != 255, simage, image)
image = image.astype(numpy.uint8)
image = _imageToPIL(image)

imageDraw = ImageDraw.Draw(image)

fontsize = 0.15
text = 'x=%d\ny=%d\nz=%d' % (x, y, z)
if hasattr(self, '_frames'):
Expand All @@ -219,7 +217,8 @@ def getTile(self, x, y, z, *args, **kwargs):
('T', 'IndexT'), ('XY', 'IndexXY')]:
if k2 in self._frames[frame]:
text += '\n%s=%d' % (k1, self._frames[frame][k2])
fontsize = min(fontsize, 0.8 / len(text.split('\n')))
text += bandtext
fontsize = min(fontsize, 0.8 / len(text.split('\n')))
try:
# the font size should fill the whole tile
imageDrawFont = ImageFont.truetype(
Expand All @@ -231,23 +230,49 @@ def getTile(self, x, y, z, *args, **kwargs):
imageDraw.multiline_text(
xy=(10, 10),
text=text,
fill=(0, 0, 0),
fill=(0, 0, 0) if band != 'alpha' else (255, 255, 255),
font=imageDrawFont
)
return image

@methodcache()
def getTile(self, x, y, z, *args, **kwargs):
frame = self._getFrame(**kwargs)
self._xyzInRange(x, y, z, frame, len(self._frames) if hasattr(self, '_frames') else None)

if not (self.minLevel <= z <= self.maxLevel):
raise TileSourceError('z layer does not exist')
_counters['tiles'] += 1
if self.monochrome:
image = image.convert('L')
if not self._bands or len(self._bands) == len(image.mode):
return self._outputTile(image, TILE_FORMAT_PIL, x, y, z, **kwargs)
image = _imageToNumpy(image)[0]
newimg = numpy.zeros((image.shape[0], image.shape[1], len(self._bands)))
newimg[:, :, :image.shape[2]] = image
for b in range(image.shape[2], len(self._bands)):
newimg[:, :, b] = (b / len(self._bands) + (1 - b / len(self._bands)) * xFraction) * 255
newimg[image[:, :, 0] == 0] = 255 if self._bands[b] in {'alpha', 'A'} else 0
newimg[image[:, :, 0] == 255] = 255
image = newimg
return self._outputTile(image, TILE_FORMAT_NUMPY, x, y, z, **kwargs)

xFraction = (x + 0.5) * self.tileWidth * 2 ** (self.levels - 1 - z) / self.sizeX
yFraction = (y + 0.5) * self.tileHeight * 2 ** (self.levels - 1 - z) / self.sizeY
fFraction = yFraction
if hasattr(self, '_frames'):
fFraction = float(frame) / (len(self._frames) - 1)

backgroundColor = colorsys.hsv_to_rgb(
h=xFraction,
s=(0.3 + (0.7 * fFraction)),
v=(0.3 + (0.7 * yFraction)),
)
rgbColor = tuple(int(val * 255) for val in backgroundColor)

if not self._bands or len(self._bands) == (1 if self.monochrome else 3):
image = self._tileImage(rgbColor, x, y, z, frame)
if self.monochrome:
image = image.convert('L')
format = TILE_FORMAT_PIL
else:
image = numpy.zeros(
(self.tileHeight, self.tileWidth, len(self._bands)), dtype=numpy.uint8)
for bandnum, band in enumerate(self._bands):
bandimg = self._tileImage(rgbColor, x, y, z, frame, band, bandnum)
bandimg = _imageToNumpy(bandimg)[0]
if self.monochrome or band.upper() in {'grey', 'gray', 'alpha'}:
bandimg = bandimg.convert('L')
image[:, :, bandnum] = bandimg[:, :, bandnum % bandimg.shape[2]]
format = TILE_FORMAT_NUMPY
return self._outputTile(image, format, x, y, z, **kwargs)

@staticmethod
def getLRUHash(*args, **kwargs):
Expand Down
4 changes: 2 additions & 2 deletions test/test_files/multi_band.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ sources:
sizeY: 7500
fractal: True
# c,z,t,xy OR frames
frames: "4,6,1,1"
frames: "4,5,1,1"
monochrome: False
# multiband
bands: "red,green,blue,ir1,ir2"
bands: "red,green,blue,ir1,ir2,grey"
2 changes: 1 addition & 1 deletion test/test_source_multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,6 @@ def testMultiBand():
imagePath = os.path.join(testDir, 'test_files', 'multi_band.yml')
source = large_image_source_multi.open(imagePath)
metadata = source.getMetadata()
assert len(metadata['bands']) == 5
assert len(metadata['bands']) == 6
image, mimeType = source.getThumbnail(encoding='PNG')
assert image[:len(utilities.PNGHeader)] == utilities.PNGHeader

0 comments on commit a662621

Please sign in to comment.