A while ago I blogged about the brotli, a new general purpose compression algorithm which Google promotes as an alternative to gzip. The same company also happens to be working on a new format for images called webp, which is actually a derivative of the VP8 video format. Google claims webp provides superior compression for both lossless (png) and lossy (jpeg) bitmaps, and even though the format is currently only supported in Google Chrome it seems promising.
The webp R package allows for reading/writing webp bitmap arrays so that we can convert between other bitmap formats. For example, let’s take this photo of a delicious and nutritious feelgoodbyfood spelt-pancake with coconut sprinkles and homemade espresso (see here for 7 other healthy winter breakfasts!)
We read the jpeg file into a bitmap and then write it to webp:
library(webp) library(jpeg) library(curl) curl_download("https://www.opencpu.org/images/pancake.jpg", "pancake.jpg") bitmap <- readJPEG("pancake.jpg") write_webp(bitmap, "pancake.webp") # Only works in Google Chrome browseURL("pancake.webp")
Of course it works the other way around as well. To read the webp image back into a bitmap and write it to png:
library(png) bitmap2 <- read_webp("pancake.webp") writePNG(bitmap2, "pancake.png") browseURL("pancake.png")
Rendering plots to webp
The easiest way to write plots in webp format is by using an svg device and render them to webp with the rsvg package (example from rsvg blog post):
# create an svg image library(svglite) library(ggplot2) svglite("plot.svg", width = 10, height = 7) qplot(mpg, wt, data = mtcars, colour = factor(cyl)) dev.off() # render it into a bitmap array library(rsvg) rsvg_webp("plot.svg", "plot.webp", width = 1920) browseURL("plot.webp")
write_webp function has a
quality parameter (integer between 1 and 100) which can be used to tune the quality-size trade-off for lossy compression. A
quality=100 equals lossless compression; the default
quality=80 provides considerable size reduction with negligible loss of quality.
library(rsvg) library(webp) tiger <- rsvg("http://dev.w3.org/SVG/tools/svgweb/samples/svg-files/tiger.svg", height = 720) write_webp(tiger, "tiger100.webp", quality = 100) write_webp(tiger, "tiger80.webp", quality = 80) write_webp(tiger, "tiger50.webp", quality = 50)
Unfortunately webp will probably not become mainstream until it gets implemented by all browsers. However it could actually be valuable for scientific applications with large image compression.