Site icon R-bloggers

Using webp in R: A New Format for Lossless and Lossy Image Compression

[This article was first published on OpenCPU, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

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")

The 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.

To leave a comment for the author, please follow the link and comment on their blog: OpenCPU.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.