This vignette is a full walkthrough of all the basic features of tinieR to shrink existing images.

For use with plots, see the “using tinieR to save plots” vignette.

To set default options for use with tinify(), see the “setting default options” vignette.

Installation

You can install the latest version of tinieR from Github with:

# install.packages("devtools")
devtools::install_github("jmablog/tinieR")

Authentication with TinyPNG

You will need an API key from TinyPNG. You can signup to get one here.

Once you have your API key, you can set it for your current R session with:

library(tinieR)

tinify_key("YOUR-API-KEY-HERE")

Or you can provide your API key as an argument to tinify() at every call:

my_key <- "YOUR-API-KEY-HERE"

tinify("example.png", key = my_key)

Providing an API key as an argument to tinify() will override any API key set with tinify_api(). This could be useful if utilising multiple API keys.

Be careful including your API key in any scripts you write, especially if you’re going to be publicly or privately sharing those scripts with others! You might consider setting your API key instead in your .Renviron file (~/.Renviron). If you use the variable name TINY_API in .Renviron, tinify() should find it, and you can skip using tinify_api() or providing an API at each call of tinify().

To edit your .Renviron in Rstudio:

usethis::edit_r_environ()

Then save into .Renviron:

TINY_API = "YOUR-API-KEY-HERE"

Restart your R session, and your TinyPNG API key will be stored as an environment variable that tinify() will automatically find.

Shrinking an image

To shrink an image file’s size, provide a path to the file relative to the current working directory.:

tinify("example.png")

#> Filesize reduced by 50%:
#> example.png (20K) => example_tiny.png (10K)
#> 10 Tinify API calls this month

By default, tinify will create a new file with the suffix ’_tiny’ in the same directory as the original file. You can change this suffix to your own using suffix = "yoursuffix":

tinify("example.png", suffix = "_small")

#> Filesize reduced by 50%:
#> example.png (20K) => example_small.png (10K)
#> 11 Tinify API calls this month

suffix must not be an empty string. To instead overwrite the original file with the newly tinified file, use overwrite = TRUE:

tinify("example.png", overwrite = TRUE)

#> Filesize reduced by 50%:
#> example.png (20K) => example.png (10K)
#> 12 Tinify API calls this month

If you use overwrite, then suffix is ignored.

Tinify will provide messages detailing the file size reduction (in % and as FS bytes) along with the number of API calls made each month when called. You can suppress these messages with quiet = TRUE:

tinify("example.png", quiet = TRUE)

Using the tinified image

Tinify can also return the file path to the tinified file, as a string, with return_path. Set to return_path = "abs" to return the absolute file path to the tinified file, which can be passed in to another function that takes an image file path to automate shrinking filesizes when, for example, knitting a document:

shrunk_img <- tinify("imgs/example.png", return_path = "abs", quiet = TRUE)

knitr::include_graphics(shrunk_img)

The return path is just a string, allowing you to actually use tinify() nested within other image functions:

knitr::include_graphics(tinify("imgs/example.png", return_path = "abs", quiet = TRUE))

Set to return_path = "proj" to return the path to the newly tinified file relative to the project directory, no matter the current working directory. This looks for an Rstudio project file (.Rproj) in the current directory or above, and returns the path from there.

setwd("imgs")

tinify("example.png", return_path = "proj", quiet = TRUE)

#> "imgs/examples.png"

Or, set to return_path = "rel" to return the file path relative to the current working directory at the time the file was tinified.

setwd("imgs")

tinify("example.png", return_path = "rel", quiet = TRUE)

#> "./examples.png"

Either of these options may be useful if sharing a script with others across platforms, if you can be sure your project setups will be the same and you are being strict with working directories. Finally, set to return_path = "all" to return all 3 types of file path as a named list:

shrunk_img_list <- tinify("imgs/example.png", return_path = "all", quiet = TRUE)

knitr::include_graphics(shrunk_img_list$absolute)
knitr::include_graphics(shrunk_img_list$project)
knitr::include_graphics(shrunk_img_list$relative)

Resizing image dimensions

You can also use the resize argument to change the image dimensions along with the filesize (note: you can only decrease an images dimensions to make it smaller with TinyPNG, not make an image bigger). I recommend reading the TinyPNG API documentation on resizing methods first, to familiarise yourself with the various options you can use to change image dimensions.

resize takes a named list, containing a method string and at least one of width or height, or both width AND height depending on your chosen resize method, to specify the dimensions in pixels you would like the image resized:

resize_opts <- list(method = "fit", width = 300, height = 150)

tinify("imgs/example.png", resize = resize_opts)

Be aware that resizing and shrinking the filesize of an image counts as 2 API calls - see below.

TinyPNG API monthly limit

TinyPNG is quite generous at 500 free API calls per month (I only hit around 50 calls in total during the entire development and testing of this package!), but if you’re using tinify() as part a script that may be run multiple times, you should be aware of your API usage. Fortunately TinyPNG is smart enough to know when you are uploading the same file over again, and so will not count repeat calls of tinify() on the exact same image file against your monthly limit. This is handy if you are using tinify() in an RMarkdown document as it won’t count against your API usage every time you knit your document. However be careful if saving new images to file from other workflows, such as creating plots, as changes to these will most likely count as new files when uploaded to TinyPNG.

Resizing an image also counts as an extra API call, as the image is first uploaded to TinyPNG and the filesize reduced, then this new image is resized with a second call to the API.

Further examples

You can combine any number of the above arguments:

tinify("example.png", overwrite = TRUE, quiet = TRUE, return_path = "abs")

Tinify also works nicely with the pipe:

img <- "example.png"

img %>% tinify()

And with purrr::map for multiple files:

imgs <- c("example.png", "example2.png")

purrr::map(imgs, ~tinify(.x))

Below is an example method for shrinking an entire directory:

imgs_dir <- fs::dir_ls("imgs", glob = "*.png")

purrr::map(imgs_dir, ~tinify(.x, overwrite = TRUE, quiet = TRUE))

Using from the command line

If you just want to quickly shrink an image in a directory, you can always just call tinify() from the command line. Just make sure tinieR is installed as a global package to your R install, then at the command line run:

R -e "tinieR::tinify('example.png')"

For this to work, you will need to ensure your TinyPNG.com API key is in your global .Renviron file, as detailed above, or else provide it explicitly at runtime with tinieR::tinify('example.png', key = 'YOUR_API_KEY').