| Title: | Optimize and Compress Images |
| Version: | 0.4 |
| Description: | Optimize and compress images using 'Rust' libraries to reduce file sizes while maintaining image quality. Supports PNG palette reduction and dithering via the 'exoquant' crate before lossless PNG optimization via the 'oxipng' crate, and JPEG re-encoding via the 'mozjpeg' crate. The package provides functions to optimize individual image files or entire directories, with configurable compression levels. Use tinyimg() as a convenient entry point for mixed PNG/JPEG workflows. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/yihui/tinyimg |
| BugReports: | https://github.com/yihui/tinyimg/issues |
| SystemRequirements: | Cargo (Rust's package manager), rustc |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.3 |
| Suggests: | testit |
| Config/rextendr/version: | 0.3.1 |
| NeedsCompilation: | yes |
| Packaged: | 2026-04-14 17:23:37 UTC; yihui |
| Author: | Yihui Xie |
| Maintainer: | Yihui Xie <xie@yihui.name> |
| Repository: | CRAN |
| Date/Publication: | 2026-04-14 18:00:03 UTC |
tinyimg: Optimize and Compress Images
Description
The tinyimg package provides tools for optimizing and compressing images
using Rust libraries. Use tinyimg() for a convenient entry point that
handles both PNG and JPEG files, tinypng() for PNG-only optimization, or
tinyjpg() for JPEG-only optimization.
Author(s)
Maintainer: Yihui Xie xie@yihui.name (ORCID) (https://yihui.org) [copyright holder]
Other contributors:
Authors of the dependency Rust crates (see AUTHORS file) [contributor, copyright holder]
See Also
Useful links:
Optimize PNG and JPEG images
Description
tinyimg() dispatches PNG files to tinypng() and JPEG files to
tinyjpg(). tinypng() optimizes PNG files using optional lossy palette
reduction and dithering (via the exoquant crate) before lossless
compression (via the oxipng crate). tinyjpg() optimizes JPEG files by
re-encoding with mozjpeg's optimized
Huffman coding and quantization tables.
Usage
tinyimg(
input,
output = tiny_output,
recursive = TRUE,
verbose = TRUE,
level = 2L,
quality = 75,
lossy = 0,
...
)
tinyjpg(
input,
output = tiny_output,
quality = 75,
recursive = TRUE,
verbose = TRUE
)
tiny_output(input, lossy = 0, quality = 75)
tinypng(
input,
output = tiny_output,
level = 2L,
alpha = FALSE,
preserve = TRUE,
recursive = TRUE,
verbose = TRUE,
lossy = 0
)
Arguments
input |
Path to an image file, a character vector of image file paths,
or a directory. |
output |
Path to the output file or directory, a function that maps
input paths to output paths, or |
recursive |
When |
verbose |
Print file size change info for each file. |
level |
PNG optimization level (0–6). Higher values give better
compression but take longer. Passed to |
quality |
JPEG quality level (0–100). Higher quality means larger
files; lower quality means smaller files. Passed to |
lossy |
Numeric threshold for per-color |
... |
Additional arguments passed from |
alpha |
Optimize transparent pixels in PNG files for better compression. This is technically lossy but visually lossless. |
preserve |
Preserve file permissions and timestamps when optimizing PNG
files. Ignored when |
Details
tiny_output() generates output file paths by appending a suffix that
encodes the optimization parameters, e.g., foo_l2.3.png for lossy PNG
(lossy = 2.3) and foo_q70.jpg for JPEG at quality = 70. It is the
default output for all three optimizers so that lossy or quality-reduced
results are never silently written over the original files. Pass
output = identity to optimize in place (lossless PNG optimization is
always safe to do in place).
The lossy PNG algorithm uses color difference in the CIE 1976
L^*a^*b^* color space. For a candidate palette size n, the image
is quantized with n colors using nearest-color mapping. Sampled pixels
are then grouped by their original color, so each distinct color gets
one equal vote regardless of how many pixels share it (preventing a large
uniform background from masking errors in rarer content colors). The
worst-case \Delta E_{76} within each group is recorded, and the
95th percentile of those per-color values is taken. Bisection on n
(1–256) finds the smallest palette whose per-color p95 is <= lossy.
\Delta E_{76} \approx 2.3 is the just noticeable difference (JND)
threshold. Larger values allow more color difference and smaller palettes,
with more loss of color fidelity.
Value
tinyimg(), tinypng(), and tinyjpg() invisibly return a
character vector of output file paths. tiny_output() returns a
character vector of output file paths (visibly).
References
https://en.wikipedia.org/wiki/Color_difference
Examples
# Create test images
tmp_png = tempfile(fileext = ".png")
png(tmp_png, width = 400, height = 400); plot(1:10); dev.off()
tmp_jpg = tempfile(fileext = ".jpg")
jpeg(tmp_jpg, width = 400, height = 400); plot(1:10); dev.off()
# Optimize both in one call (uses tiny_output() by default)
tinyimg(c(tmp_png, tmp_jpg))
# Optimize in place (lossless PNG is safe; use with care for JPEG)
tinypng(tmp_png, identity)
tinyjpg(tmp_jpg, identity)
# Lossy PNG: output gets a suffix automatically
tinypng(tmp_png, lossy = 2.3)
# JPEG at a specific quality
tinyjpg(tmp_jpg, quality = 60)
# See what output names tiny_output() would generate
tiny_output(c(tmp_png, tmp_jpg), lossy = 2.3, quality = 60)