The resmush package has recently been accepted on CRAN! This small utility package allows for the optimization (i.e., compression) of local and online images using reSmush.it.
You can install resmush from CRAN with:
install.packages("resmush")
What is reSmush.it?
reSmush.it is a free online API that provides image optimization and has been implemented on WordPress, Drupal, or Magento. Some features of reSmush.it include:
- Free optimization services, no API key required.
- Optimization of local and online images.
- Supported image file formats: PNG, JPG/JPEG, GIF, BMP, TIFF, WebP.
- Maximum image size: 5 MB.
- Compression using several algorithms:
reSmush.it is free of charge, but its team is planning to offer more serves as well as extend the service to support other types of image files. If you enjoy this API (as I do), you can consider supporting them.
Why the resmush package?
One of the main reasons I developed resmush is because I usually include precomputed vignettes with my packages (see tidyterra as an example). I found that the plots created on CRAN with the standard configuration (i.e., not precomputed vignettes but built on CRAN itself) were not very satisfying. In some of the packages I developed, especially those related to mapping, they didn’t do justice to the actual results when a user runs them.
Precomputing vignettes has the drawback of producing higher-quality images at the expense of size. To avoid exceeding CRAN’s 5Mb maximum size policy, I developed resmush, which enables me to reduce the size of the images without a significant loss in quality.
Another use case for resmush is optimizing images in the context of web page
development and SEO optimization. For example, I optimized all the images on
this blog using resmush_dir()
, which is a shorthand for optimizing all files
in a specific folder.
There are other alternatives that I would discuss at the end of this post, but in one line, the reSmush.it API performs fast with minimal configuration for a wide range of formats without needing an API key.
Using the resmush package
With local files
Let’s present an example of how a local file can be optimized. First we create a large plot with ggplot2
library(tidyterra)
library(ggplot2)
library(terra)
library(maptiles)
cyl <- vect(system.file("extdata/cyl.gpkg", package = "tidyterra")) %>%
project("EPSG:3857")
cyl_img <- get_tiles(cyl, "Esri.WorldImagery", zoom = 8, crop = TRUE)
cyl_gg <- autoplot(cyl_img, maxcell = Inf) +
geom_spatvector(data = cyl, alpha = 0.3)
cyl_gg
# And we save it for resmushing
ggsave("cyl.png", width = 5, height = 0.7 * 5)
Cool, but the file has a size of 1.7 Mb. So we can use resmush_file()
to
reduce it, see:
library(resmush)
resmush_file("cyl.png")
#> ══ resmush summary ══════════════════════════════════════════
#> ℹ Input: 1 file with size 1.7 Mb
#> ✔ Success for 1 file: Size now is 762.2 Kb (was 1.7 Mb). Saved 948.9 Kb (55.46%).
#> See result in directory '.'.
# Check
png::readPNG("cyl_resmush.png") %>%
grid::grid.raster()
By default, resmush_file()
and resmush_dir()
do not overwrite the original
file, although this behavior may be modified with the overwrite = TRUE
parameter. Now, the resmushed file ("cyl_resmush.png"
) has a size of 762.2 Kb.
Let’s compare the results side-by-side:
We can verify that the image has been compressed without reducing its dimensions.
size_src <- file.size("cyl.png") %>%
`class<-`("object_size") %>%
format(units = "auto")
size_dest <- file.size("cyl_resmush.png") %>%
`class<-`("object_size") %>%
format(units = "auto")
dim_src <- dim(png::readPNG("cyl.png"))[1:2] %>% paste0(collapse = "x")
dim_dest <- dim(png::readPNG("cyl_resmush.png"))[1:2] %>% paste0(collapse = "x")
data.frame(
source = c("original file", "compressed file"),
size = c(size_src, size_dest),
dimensions = c(dim_src, dim_dest)
) %>%
knitr::kable()
source | size | dimensions |
---|---|---|
original file | 1.7 Mb | 1050x1500 |
compressed file | 762.2 Kb | 1050x1500 |
With online files
We can also optimize online files with resmush_url()
and download them to
disk. In this example, I demonstrate a feature of all the functions in
resmush: they return an invisible data frame with a summary of the process.
url <- "https://dieghernan.github.io/assets/img/samples/sample_1.3mb.jpg"
# Invisible data frame
dm <- resmush_url(url, "sample_optimized.jpg", report = FALSE)
knitr::kable(dm)
src_img | dest_img | src_size | dest_size | compress_ratio | notes | src_bytes | dest_bytes |
---|---|---|---|---|---|---|---|
https://dieghernan.github.io/assets/img/samples/sample_1.3mb.jpg | sample_optimized.jpg | 1.3 Mb | 985 Kb | 26.63% | OK | 1374693 | 1008593 |
Other alternatives
There are other alternatives for optimizing images with R, but first…
Yihui Xie, one of the most prominent figures in the R community, was recently laid off from his position at Posit PBC (formerly RStudio) (more info here).
Yihui is the developer of knitr, markdown, blogdown, and bookdown, among others, and he has been one of the key contributors (if not the most) to the reproducible research space with R through his libraries.
If you have ever used and enjoyed his packages, consider sponsoring him on GitHub.
- One of the many packages developed by Yihui is
xfun, which includes the
following functions for optimizing image files:
xfun::tinify()
is similar toresmush_file()
but uses TinyPNG. An API key is required.xfun::optipng()
compresses local files with OptiPNG (which needs to be installed locally).
- tinieR package by jmablog. An R package that provides a full interface with TinyPNG.
- optout package by
@coolbutuseless. Similar to
xfun::optipng()
with additional options. Requires additional software to be installed locally.
tool | CRAN | Additional software? | Online? | API Key? | Limits? |
---|---|---|---|---|---|
xfun::tinify() |
Yes | No | Yes | Yes | 500 files/month (Free tier) |
xfun::optipng() |
Yes | Yes | No | No | No |
tinieR | No | No | Yes | Yes | 500 files/month (Free tier) |
optout | No | Yes | No | No | No |
resmush | Yes | No | Yes | No | Max size 5Mb |
tool | png | jpg | gif | bmp | tiff | webp | |
---|---|---|---|---|---|---|---|
xfun::tinify() |
✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ |
xfun::optipng() |
✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ |
tinieR | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ | ❌ |
optout | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ✅ |
resmush | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
Additionally, if you host your projects on GitHub, you can try Imgbot, which is free for open-source projects. Imgbot provides automatic optimization for files in your repositories, and the optimized files will be included in specific pull requests before merging into your work.