% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/tinyimg.R, R/tinyjpg.R, R/tinypng.R
\name{tinyimg}
\alias{tinyimg}
\alias{tinyjpg}
\alias{tiny_output}
\alias{tinypng}
\title{Optimize PNG and JPEG images}
\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{
\item{input}{Path to an image file, a character vector of image file paths,
or a directory. \code{tinyimg()} accepts \code{.png}, \code{.apng}, \code{.jpg}, and \code{.jpeg}
files; \code{tinypng()} accepts \code{.png} and \code{.apng}; \code{tinyjpg()} accepts
\code{.jpg} and \code{.jpeg}.}

\item{output}{Path to the output file or directory, a function that maps
input paths to output paths, or \code{identity} to optimize in place.
Defaults to \code{\link[=tiny_output]{tiny_output()}}, which adds a suffix encoding the
optimization parameters so that the original file is never overwritten
by a lossy result.}

\item{recursive}{When \code{input} is a directory, also search subdirectories.}

\item{verbose}{Print file size change info for each file.}

\item{level}{PNG optimization level (0--6). Higher values give better
compression but take longer. Passed to \code{tinypng()} by \code{tinyimg()}.}

\item{quality}{JPEG quality level (0--100). Higher quality means larger
files; lower quality means smaller files. Passed to \code{tinyjpg()} by
\code{tinyimg()}. \code{tiny_output()} appends \verb{_q<value>} when \code{quality < 100}.}

\item{lossy}{Numeric threshold for per-color \eqn{\Delta E_{76}} in lossy
PNG palette reduction. Values \verb{<= 0} disable lossy optimization. See
Details. Passed to \code{tinypng()} by \code{tinyimg()} via \code{...}. When \verb{> 0},
\code{tiny_output()} appends \verb{_l<value>} to the output filename.}

\item{...}{Additional arguments passed from \code{tinyimg()} to \code{tinypng()}
(e.g., \code{alpha}, \code{preserve}).}

\item{alpha}{Optimize transparent pixels in PNG files for better
compression. This is technically lossy but visually lossless.}

\item{preserve}{Preserve file permissions and timestamps when optimizing PNG
files. Ignored when \code{lossy > 0}.}
}
\value{
\code{tinyimg()}, \code{tinypng()}, and \code{tinyjpg()} invisibly return a
character vector of output file paths. \code{tiny_output()} returns a
character vector of output file paths (visibly).
}
\description{
\code{tinyimg()} dispatches PNG files to \code{tinypng()} and JPEG files to
\code{tinyjpg()}. \code{tinypng()} optimizes PNG files using optional lossy palette
reduction and dithering (via the \code{exoquant} crate) before lossless
compression (via the \code{oxipng} crate). \code{tinyjpg()} optimizes JPEG files by
re-encoding with \href{https://github.com/mozilla/mozjpeg}{mozjpeg}'s optimized
Huffman coding and quantization tables.
}
\details{
\code{tiny_output()} generates output file paths by appending a suffix that
encodes the optimization parameters, e.g., \code{foo_l2.3.png} for lossy PNG
(\code{lossy = 2.3}) and \code{foo_q70.jpg} for JPEG at \code{quality = 70}. It is the
default \code{output} for all three optimizers so that lossy or quality-reduced
results are never silently written over the original files. Pass
\code{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
\eqn{L^*a^*b^*} color space. For a candidate palette size \code{n}, the image
is quantized with \code{n} colors using nearest-color mapping. Sampled pixels
are then \strong{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 \eqn{\Delta E_{76}} within each group is recorded, and the
95th percentile of those per-color values is taken. Bisection on \code{n}
(1--256) finds the smallest palette whose per-color p95 is \verb{<= lossy}.

\eqn{\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.
}
\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)
}
\references{
\url{https://en.wikipedia.org/wiki/Color_difference}
}
