Skip to content

Commit

Permalink
Merge pull request #936 from girder/test-source-bands-fancy
Browse files Browse the repository at this point in the history
Make the test source banded images fancier.
  • Loading branch information
manthey authored Aug 17, 2022
2 parents 143446f + a662621 commit 2291ec7
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 2291ec7

Please sign in to comment.