Add support for WebP images (#6311)

This commit is contained in:
Linus Unnebäck 2025-06-04 11:54:03 +02:00 committed by GitHub
parent 5f776c7372
commit 1de2095f67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 17 additions and 6 deletions

1
Cargo.lock generated
View File

@ -1215,6 +1215,7 @@ dependencies = [
"byteorder-lite", "byteorder-lite",
"color_quant", "color_quant",
"gif", "gif",
"image-webp",
"num-traits", "num-traits",
"png", "png",
"zune-core", "zune-core",

View File

@ -69,7 +69,7 @@ icu_provider_adapters = "1.4"
icu_provider_blob = "1.4" icu_provider_blob = "1.4"
icu_segmenter = { version = "1.4", features = ["serde"] } icu_segmenter = { version = "1.4", features = ["serde"] }
if_chain = "1" if_chain = "1"
image = { version = "0.25.5", default-features = false, features = ["png", "jpeg", "gif"] } image = { version = "0.25.5", default-features = false, features = ["png", "jpeg", "gif", "webp"] }
indexmap = { version = "2", features = ["serde"] } indexmap = { version = "2", features = ["serde"] }
infer = { version = "0.19.0", default-features = false } infer = { version = "0.19.0", default-features = false }
kamadak-exif = "0.6" kamadak-exif = "0.6"

View File

@ -841,7 +841,9 @@ fn param_value_completions<'a>(
/// Returns which file extensions to complete for the given parameter if any. /// Returns which file extensions to complete for the given parameter if any.
fn path_completion(func: &Func, param: &ParamInfo) -> Option<&'static [&'static str]> { fn path_completion(func: &Func, param: &ParamInfo) -> Option<&'static [&'static str]> {
Some(match (func.name(), param.name) { Some(match (func.name(), param.name) {
(Some("image"), "source") => &["png", "jpg", "jpeg", "gif", "svg", "svgz"], (Some("image"), "source") => {
&["png", "jpg", "jpeg", "gif", "svg", "svgz", "webp"]
}
(Some("csv"), "source") => &["csv"], (Some("csv"), "source") => &["csv"],
(Some("plugin"), "source") => &["wasm"], (Some("plugin"), "source") => &["wasm"],
(Some("cbor"), "source") => &["cbor"], (Some("cbor"), "source") => &["cbor"],

View File

@ -147,6 +147,7 @@ fn determine_format(source: &DataSource, data: &Bytes) -> StrResult<ImageFormat>
"jpg" | "jpeg" => return Ok(ExchangeFormat::Jpg.into()), "jpg" | "jpeg" => return Ok(ExchangeFormat::Jpg.into()),
"gif" => return Ok(ExchangeFormat::Gif.into()), "gif" => return Ok(ExchangeFormat::Gif.into()),
"svg" | "svgz" => return Ok(VectorFormat::Svg.into()), "svg" | "svgz" => return Ok(VectorFormat::Svg.into()),
"webp" => return Ok(ExchangeFormat::Webp.into()),
_ => {} _ => {}
} }
} }

View File

@ -77,8 +77,8 @@ pub struct ImageElem {
/// [`source`]($image.source) (even then, Typst will try to figure out the /// [`source`]($image.source) (even then, Typst will try to figure out the
/// format automatically, but that's not always possible). /// format automatically, but that's not always possible).
/// ///
/// Supported formats are `{"png"}`, `{"jpg"}`, `{"gif"}`, `{"svg"}` as well /// Supported formats are `{"png"}`, `{"jpg"}`, `{"gif"}`, `{"svg"}`,
/// as raw pixel data. Embedding PDFs as images is /// `{"webp"}` as well as raw pixel data. Embedding PDFs as images is
/// [not currently supported](https://github.com/typst/typst/issues/145). /// [not currently supported](https://github.com/typst/typst/issues/145).
/// ///
/// When providing raw pixel data as the `source`, you must specify a /// When providing raw pixel data as the `source`, you must specify a

View File

@ -9,6 +9,7 @@ use ecow::{eco_format, EcoString};
use image::codecs::gif::GifDecoder; use image::codecs::gif::GifDecoder;
use image::codecs::jpeg::JpegDecoder; use image::codecs::jpeg::JpegDecoder;
use image::codecs::png::PngDecoder; use image::codecs::png::PngDecoder;
use image::codecs::webp::WebPDecoder;
use image::{ use image::{
guess_format, DynamicImage, ImageBuffer, ImageDecoder, ImageResult, Limits, Pixel, guess_format, DynamicImage, ImageBuffer, ImageDecoder, ImageResult, Limits, Pixel,
}; };
@ -77,6 +78,7 @@ impl RasterImage {
ExchangeFormat::Jpg => decode(JpegDecoder::new(cursor), icc), ExchangeFormat::Jpg => decode(JpegDecoder::new(cursor), icc),
ExchangeFormat::Png => decode(PngDecoder::new(cursor), icc), ExchangeFormat::Png => decode(PngDecoder::new(cursor), icc),
ExchangeFormat::Gif => decode(GifDecoder::new(cursor), icc), ExchangeFormat::Gif => decode(GifDecoder::new(cursor), icc),
ExchangeFormat::Webp => decode(WebPDecoder::new(cursor), icc),
} }
.map_err(format_image_error)?; .map_err(format_image_error)?;
@ -242,6 +244,8 @@ pub enum ExchangeFormat {
/// Raster format that is typically used for short animated clips. Typst can /// Raster format that is typically used for short animated clips. Typst can
/// load GIFs, but they will become static. /// load GIFs, but they will become static.
Gif, Gif,
/// Raster format that supports both lossy and lossless compression.
Webp,
} }
impl ExchangeFormat { impl ExchangeFormat {
@ -257,6 +261,7 @@ impl From<ExchangeFormat> for image::ImageFormat {
ExchangeFormat::Png => image::ImageFormat::Png, ExchangeFormat::Png => image::ImageFormat::Png,
ExchangeFormat::Jpg => image::ImageFormat::Jpeg, ExchangeFormat::Jpg => image::ImageFormat::Jpeg,
ExchangeFormat::Gif => image::ImageFormat::Gif, ExchangeFormat::Gif => image::ImageFormat::Gif,
ExchangeFormat::Webp => image::ImageFormat::WebP,
} }
} }
} }
@ -269,6 +274,7 @@ impl TryFrom<image::ImageFormat> for ExchangeFormat {
image::ImageFormat::Png => ExchangeFormat::Png, image::ImageFormat::Png => ExchangeFormat::Png,
image::ImageFormat::Jpeg => ExchangeFormat::Jpg, image::ImageFormat::Jpeg => ExchangeFormat::Jpg,
image::ImageFormat::Gif => ExchangeFormat::Gif, image::ImageFormat::Gif => ExchangeFormat::Gif,
image::ImageFormat::WebP => ExchangeFormat::Webp,
_ => bail!("format not yet supported"), _ => bail!("format not yet supported"),
}) })
} }

View File

@ -45,6 +45,7 @@ pub fn convert_image_to_base64_url(image: &Image) -> EcoString {
ExchangeFormat::Png => "png", ExchangeFormat::Png => "png",
ExchangeFormat::Jpg => "jpeg", ExchangeFormat::Jpg => "jpeg",
ExchangeFormat::Gif => "gif", ExchangeFormat::Gif => "gif",
ExchangeFormat::Webp => "webp",
}, },
raster.data(), raster.data(),
), ),

View File

@ -69,7 +69,7 @@ the first item of the list above by indenting it.
## Adding a figure { #figure } ## Adding a figure { #figure }
You think that your report would benefit from a figure. Let's add one. Typst You think that your report would benefit from a figure. Let's add one. Typst
supports images in the formats PNG, JPEG, GIF, and SVG. To add an image file to supports images in the formats PNG, JPEG, GIF, SVG, and WebP. To add an image file to
your project, first open the _file panel_ by clicking the box icon in the left your project, first open the _file panel_ by clicking the box icon in the left
sidebar. Here, you can see a list of all files in your project. Currently, there sidebar. Here, you can see a list of all files in your project. Currently, there
is only one: The main Typst file you are writing in. To upload another file, is only one: The main Typst file you are writing in. To upload another file,

View File

@ -243,7 +243,7 @@ A #box(image("/assets/images/tiger.jpg", height: 1cm, width: 80%)) B
--- image-png-but-pixmap-format --- --- image-png-but-pixmap-format ---
#image( #image(
read("/assets/images/tiger.jpg", encoding: none), read("/assets/images/tiger.jpg", encoding: none),
// Error: 11-18 expected "png", "jpg", "gif", dictionary, "svg", or auto // Error: 11-18 expected "png", "jpg", "gif", "webp", dictionary, "svg", or auto
format: "rgba8", format: "rgba8",
) )