中文文档 · English
lua_webp is a Lua C extension for WebP image conversion. It exposes
cwebp- and dwebp-style entry points:
- cwebp — compress PNG, JPEG, TIFF, WebP and PNM images into WebP
- dwebp — decompress WebP into PNG, PPM, PAM, BMP, TIFF, PGM, YUV and raw pixel formats
The module is built on the libwebp
public API plus the libwebp imageio glue (vendored under
third_party/libwebp, libwebp v1.4.0). When a system libwebp is not found via
pkg-config, the vendored source tree is built with CMake, so a clone of this
repo is enough to build the module.
- A C99 compiler
- Lua 5.3 or newer
pkg-config- System development packages, found via
pkg-config:libwebp>= 1.3.0 +libwebpdemux(an older system libwebp, e.g. Ubuntu 22.04's 1.2.x, is detected and the vendored build is used instead)libpng,libjpeg,libtiff(for the PNG/JPEG/TIFF input readers)cmake(only when no suitable system libwebp is available — the vendored fallback)
Install examples:
# Debian / Ubuntu
sudo apt-get install build-essential pkg-config lua5.4 liblua5.4-dev \
libwebp-dev libpng-dev libjpeg-dev libtiff-dev
# macOS (Homebrew)
brew install pkgconf lua@5.4 webp libpng jpeg-turbo libtiff
# Windows (MSYS2 / UCRT64)
pacman -S mingw-w64-ucrt-x86_64-gcc mingw-w64-ucrt-x86_64-make \
mingw-w64-ucrt-x86_64-pkgconf mingw-w64-ucrt-x86_64-lua54 \
mingw-w64-ucrt-x86_64-libwebp mingw-w64-ucrt-x86_64-libpng \
mingw-w64-ucrt-x86_64-libjpeg-turbo mingw-w64-ucrt-x86_64-libtiffmake buildYou can choose the Lua version at build time:
make LUA_VERSION=5.3 build
make LUA_VERSION=5.4 buildmake testThe test suite (tests/test.lua, ~200 assertions) covers module loading,
file and memory encoding, lossless pixel-exact round-trips (PPM/PAM),
PNG/BMP/TIFF/YUV decoding, encoder quality, decoder options (crop, scale,
threads, flip, dithering), TIFF/PNM/WebP inputs, animated-WebP detection
and error handling. Fixtures are committed under tests/ and can be
regenerated with make fixtures (the CI vendored-fallback job re-runs the
suite against regenerated fixtures to keep generator and tests in sync).
.github/workflows/ci.yml runs on every push/PR:
| Job | Runner | Steps |
|---|---|---|
linux | ubuntu-latest × {5.3, 5.4} | make build → make test with -Werror |
macos | macos-latest (5.4) | same (Homebrew lua@5.4 via PKG_CONFIG_PATH/LUA_BIN) |
windows | windows-latest (5.4) | MSYS2 UCRT64 → mingw32-make build/test with -Werror |
vendored-fallback | ubuntu-latest (5.4) | builds against the vendored libwebp via CMake (no system libwebp), then regenerates fixtures and re-runs the suite |
All jobs compile with -O2 -std=c99 -Wall -Wextra -Werror; the
vendored-fallback job proves the "clone is enough to build" path and keeps
fixtures reproducible. .github/workflows/release.yml runs on v* tags and
publishes prebuilt modules for Linux, macOS and Windows.
localwebp=require"lua_webp"localcwebp=webp.cwebplocaldwebp=webp.dwebp-- Encode a file to WebP (full encoder configuration is optional)localoutWebp=cwebp:path2Webp("test.jpg", { quality=75, method=4 })
localfile=io.open("test.webp", "wb")
file:write(outWebp)
file:close()
-- Encode image bytes to WebPlocalf=io.open("test.jpg", "rb")
localjpgData=f:read("*a")
f:close()
localoutWebp2=cwebp:image2Webp(jpgData, { lossless=1 })
io.open("test2.webp", "wb"):write(outWebp2):close()
-- Decode a WebP file to PNG (decoder options are optional)localpng=dwebp:path2Image("test.webp", "png", { use_threads=1 })
io.open("webp2png1.png", "wb"):write(png):close()
-- Decode WebP bytes to PPMlocalppm=dwebp:webp2Image(outWebp2, "ppm", {})
io.open("webp2ppm2.ppm", "wb"):write(ppm):close()| Function | Returns |
|---|---|
cwebp:path2Webp(path, config?) | WebP bytes (string) |
cwebp:image2Webp(data, config?) | WebP bytes (string) |
dwebp:path2Image(path, format, options?) | image bytes (string) |
dwebp:webp2Image(data, format, options?) | image bytes, or bytes, width, height for forced colorspaces |
dwebp:info(data) | info table |
dwebp:infoFromPath(path) | info table |
webp.version() | { encoder, decoder } |
Maps directly onto libwebp's WebPConfig (see src/webp/encode.h for the
full list). All fields are numbers unless noted. Unknown fields and
out-of-range values raise a Lua error.
| Field | Range / values | Meaning |
|---|---|---|
quality | 0–100 | lossy quality (75 default) |
lossless | 0 or 1 | lossless encoding |
method | 0–6 | quality/speed trade-off |
target_size | ≥ 0 | desired output size in bytes |
target_PSNR | ≥ 0 | minimal distortion target |
segments, sns_strength, filter_strength, filter_sharpness, filter_type | — | VP8 analysis / filtering |
autofilter | 0 or 1 | auto filter strength |
alpha_compression, alpha_filtering, alpha_quality | — | alpha plane coding |
pass | 1–10 | entropy-analysis passes |
preprocessing, partitions, partition_limit | — | internal knobs |
emulate_jpeg_size, thread_level, low_memory | — | |
near_lossless | 0–100 | near-lossless strength |
exact | 0 or 1 | preserve exact RGB values |
use_delta_palette, use_sharp_yuv | 0 or 1 | |
qmin, qmax | 0–100 | quality factor bounds |
image_hint | "photo" | "picture" | "graph" | "default" | int | image type hint (also accepts the raw WEBP_HINT_* value) |
| Category | Values | Returns |
|---|---|---|
| container | png, ppm, pam, bmp, tiff, pgm, yuv, yuva, alpha (alias: alpha_plane_only) | single string (file bytes) |
| forced colorspace | RGB, BGR — 3 bytes/px | bytes, width, height |
| forced colorspace | RGBA, BGRA, ARGB, rgbA, bgrA, Argb — 4 bytes/px | bytes, width, height |
| forced colorspace | RGBA_4444, RGB_565, rgbA_4444 — 2 bytes/px | bytes, width, height |
Forced colorspaces return raw, tightly packed pixel bytes (no stride padding) plus their dimensions:
localbytes, w, h=dwebp:webp2Image(data, "RGBA") -- w*h*4 byteslocalrgb, w, h=dwebp:webp2Image(data, "RGB") -- w*h*3 bytesMaps directly onto libwebp's WebPDecoderOptions. All fields are numbers.
| Field | Meaning |
|---|---|
use_threads | multi-threaded decoding |
use_cropping + crop_left, crop_top, crop_width, crop_height | crop the output |
use_scaling + scaled_width, scaled_height | scale the output (after cropping) |
flip | flip output vertically |
bypass_filtering | skip in-loop filtering |
no_fancy_upsampling | use faster pointwise upsampler |
dithering_strength | 0–100, dithering strength |
alpha_dithering_strength | 0–100, alpha-plane dithering |
dwebp:info(data) / dwebp:infoFromPath(path) return:
| Field | Type | Meaning |
|---|---|---|
width, height | integer | pixel dimensions |
has_alpha | boolean | bitstream contains an alpha channel |
has_animation | boolean | bitstream is an animation |
format | string | "undefined", "lossy", or "lossless" |
All failures raise Lua errors with descriptive messages. Animated WebP files
are not supported: decoding one raises an error rather than silently
using the first frame, so check info()'s has_animation first and handle
animations separately.
The simplest path is a source build:
make buildWith LuaRocks:
luarocks make lua-webp-scm-1.rockspecTagged GitHub releases publish prebuilt module artifacts for Linux, macOS and
Windows (see the release workflow); drop the matching asset next to your
Lua package path.
MIT. See LICENSE. The vendored libwebp tree is BSD-licensed
(see third_party/libwebp/COPYING and third_party/libwebp/PATENTS).