renderthis icon indicating copy to clipboard operation
renderthis copied to clipboard

Add `resize_images()` function

Open jhelvy opened this issue 4 years ago • 4 comments

Based on this tweet thread, it would be helpful to be able to batch resize all of the images used in making xaringan slides to reduce the final file size of the PDF from build_pdf() or any of the other build_* functions. This should probably be implemented at the .Rmd level and maybe parse through the .Rmd file to look for all image types that can be resized. Template I'm thinking for the function is:

resize_images <- function(input, max_size = 1, image_types = c("png", "jpeg", "jpg") {}

Where max_size is the max image file size in MB, and image_types is the vector containing all image types to search for (the user can add more if they want).

Christophe Dervieux gave some suggestions in the tweet for how to do the resizing:

Optipng can be used to optimize image size. There is a hook: https://bookdown.org/yihui/rmarkdown-cookbook/optipng.html But also xfun::optipng() https://rdrr.io/cran/xfun/man/optipng.html They can also be compressed if needed and the new tinyfy() can help: https://rdrr.io/cran/xfun/man/tinify.html

jhelvy avatar Jun 21 '21 10:06 jhelvy

Since we already import magick, I think we could do some simple rescaling, since that's the low-hanging fruit that most people miss. It's easy to download an image that's 6,500px × 5,285px and 32MB and drop it into your slides. It'll look great locally but really slow down loading when you post the slide (or turn your slides into 200MB+ standalone files). Just a simple rescaling down to 1,200px wide would make a huge difference.

I like xfun::optipng() and use it frequently, but it does introduce another system-level dependency, so I'd be interested to see what we can do with magick first.

Also, I think it might be better to post process the rendered .html file since figure outputs can also get larger than anticipated. rmarkdown has a find_external_resources() function that can be applied to an .html file (or an .Rmd for that matter) and the output can be used to find "local" external resources. Actually, now that I'm writing this, we might need to use that function on the .Rmd if self_contained = TRUE, since in that case it's too late once the .html file exist.

gadenbuie avatar Dec 14 '21 16:12 gadenbuie

Looks like magick::image_scale() might do the trick: https://cran.r-project.org/web/packages/magick/vignettes/intro.html#Transformations

jhelvy avatar Dec 14 '21 17:12 jhelvy

I also just bumped into the tinieR R package via https://jmablog.com/post/tinier-0.4.1/

gadenbuie avatar Dec 15 '21 16:12 gadenbuie

I also just bumped into the tinieR R package via https://jmablog.com/post/tinier-0.4.1/

Oooo very interesting. Though it looks like it requires an API key, which could complicate things. A magick solution would be my preference if we can make it work since we've already imported it.

jhelvy avatar Dec 15 '21 17:12 jhelvy