0

Add WebP image format support

Since Firefox 65 added support for WebP, users may be interested
in having maps that use WebP images. Support for this is added in
this commit, along with documentation for it.

A new option, "imglossless", controls whether we write out lossless
or lossy WebP images. The generic name "imglossless" as opposed to
a more specific "webplossless" was chosen in case future image
formats we also implement also support lossless/lossy modes in the
same format (JPEG-XL? AV1 image format?).

It's an okay meme but lossy mode really falls apart on our sorts
of images on the more zoomed out composite tiles, resulting in
pretty blurry messes. Might be due to a PSNR bias in the encoder,
which is to be expected from Google.
This commit is contained in:
Nicolas F
2019-03-04 17:04:09 +01:00
parent 7f63dfe315
commit 61ebd35240
5 changed files with 46 additions and 11 deletions

View File

@@ -261,12 +261,15 @@ class TileSet(object):
rest of this discussion.
imgformat
A string indicating the output format. Must be one of 'png' or
'jpeg'
A string indicating the output format. Must be one of 'png',
'jpeg' or 'webp'
imgquality
An integer 1-100 indicating the quality of the jpeg output. Only
relevant in jpeg mode.
relevant in jpeg and webp mode.
imglossless
A boolean indicating whether to save a webp image in lossless mode.
optimizeimg
A list of optimizer instances to use.
@@ -387,8 +390,10 @@ class TileSet(object):
self.imgextension = 'png'
elif self.options['imgformat'] in ('jpeg', 'jpg'):
self.imgextension = 'jpg'
elif self.options['imgformat'] == 'webp':
self.imgextension = 'webp'
else:
raise ValueError("imgformat must be one of: 'png' or 'jpg'")
raise ValueError("imgformat must be one of: 'png', 'jpg' or 'webp'")
# This sets self.treedepth, self.xradius, and self.yradius
self._set_map_size()
@@ -1000,8 +1005,11 @@ class TileSet(object):
if imgformat == 'jpg':
img.convert('RGB').save(tmppath, "jpeg", quality=self.options['imgquality'],
subsampling=0)
else: # PNG
elif imgformat == 'png': # PNG
img.save(tmppath, "png")
elif imgformat == 'webp':
img.save(tmppath, "webp", quality=self.options['imgquality'],
lossless=self.options['imglossless'])
if self.options['optimizeimg']:
optimize_image(tmppath, imgformat, self.options['optimizeimg'])
@@ -1101,8 +1109,11 @@ class TileSet(object):
if self.imgextension == 'jpg':
tileimg.convert('RGB').save(tmppath, "jpeg", quality=self.options['imgquality'],
subsampling=0)
else: # PNG
elif self.imgextension == 'png': # PNG
tileimg.save(tmppath, "png")
elif self.imgextension == 'webp':
tileimg.save(tmppath, "webp", quality=self.options['imgquality'],
lossless=self.options['imglossless'])
if self.options['optimizeimg']:
optimize_image(tmppath, self.imgextension, self.options['optimizeimg'])
os.utime(tmppath, (max_chunk_mtime, max_chunk_mtime))