feat(natives/wasm): added GIF and WebP export methods to PhotonImage

- Added `get_bytes_gif()` method to PhotonImage for exporting images as GIF bytes.
- Added `get_bytes_webp()` method to PhotonImage for exporting images as lossless WebP bytes.
- Enabled 'gif' and 'webp' features for the image crate dependency.
This commit is contained in:
can1357
2026-01-30 01:06:13 +01:00
parent 8248b9e5ef
commit 47dc81720c
7 changed files with 121 additions and 3 deletions
Generated
+41
View File
@@ -109,6 +109,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "console_error_panic_hook"
version = "0.1.7"
@@ -210,6 +216,16 @@ dependencies = [
"new_debug_unreachable",
]
[[package]]
name = "gif"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5df2ba84018d80c213569363bdcd0c64e6933c67fe4c1d60ecf822971a3c35e"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "grep-matcher"
version = "0.1.8"
@@ -302,6 +318,9 @@ checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a"
dependencies = [
"bytemuck",
"byteorder-lite",
"color_quant",
"gif",
"image-webp",
"moxcms",
"num-traits",
"png",
@@ -309,6 +328,16 @@ dependencies = [
"zune-jpeg",
]
[[package]]
name = "image-webp"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "525e9ff3e1a4be2fbea1fdf0e98686a6d98b4d8f937e1bf7402245af1909e8c3"
dependencies = [
"byteorder-lite",
"quick-error",
]
[[package]]
name = "js-sys"
version = "0.3.85"
@@ -551,6 +580,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "quick-error"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]]
name = "quote"
version = "1.0.44"
@@ -859,6 +894,12 @@ dependencies = [
"string_cache_codegen",
]
[[package]]
name = "weezl"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
[[package]]
name = "winapi-util"
version = "0.1.11"
+1 -1
View File
@@ -19,7 +19,7 @@ serde-wasm-bindgen = "0.6"
grep-regex = "0.1.14"
grep-searcher = "0.1.16"
grep-matcher = "0.1.8"
image = { version = "0.25", default-features = false, features = ["png", "jpeg"] }
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "gif", "webp"] }
unicode-segmentation = "1.11"
unicode-width = "0.2"
syntect = { version = "5.3", default-features = false, features = ["default-syntaxes", "default-themes", "regex-fancy"] }
+23
View File
@@ -91,6 +91,29 @@ impl PhotonImage {
.map_err(|e| JsValue::from_str(&format!("Failed to encode JPEG: {e}")))?;
Ok(buffer)
}
/// Export image as lossless WebP bytes.
#[wasm_bindgen(js_name = get_bytes_webp)]
pub fn get_bytes_webp(&self) -> Result<Vec<u8>, JsValue> {
let mut buffer = Vec::new();
let encoder = image::codecs::webp::WebPEncoder::new_lossless(&mut buffer);
self
.img
.write_with_encoder(encoder)
.map_err(|e| JsValue::from_str(&format!("Failed to encode WebP: {e}")))?;
Ok(buffer)
}
/// Export image as GIF bytes.
#[wasm_bindgen(js_name = get_bytes_gif)]
pub fn get_bytes_gif(&self) -> Result<Vec<u8>, JsValue> {
let mut buffer = Vec::new();
self
.img
.write_to(&mut Cursor::new(&mut buffer), ImageFormat::Gif)
.map_err(|e| JsValue::from_str(&format!("Failed to encode GIF: {e}")))?;
Ok(buffer)
}
}
/// Resize an image to the specified dimensions.
+8
View File
@@ -42,10 +42,18 @@ export class PhotonImage {
* Export image as PNG bytes.
*/
get_bytes(): Uint8Array;
/**
* Export image as GIF bytes.
*/
get_bytes_gif(): Uint8Array;
/**
* Export image as JPEG bytes with specified quality (0-100).
*/
get_bytes_jpeg(quality: number): Uint8Array;
/**
* Export image as lossless WebP bytes.
*/
get_bytes_webp(): Uint8Array;
/**
* Get the height of the image.
*/
+44
View File
@@ -133,6 +133,28 @@ export class PhotonImage {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
/**
* Export image as GIF bytes.
* @returns {Uint8Array}
*/
get_bytes_gif() {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
wasm.photonimage_get_bytes_gif(retptr, this.__wbg_ptr);
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
if (r3) {
throw takeObject(r2);
}
var v1 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_export3(r0, r1 * 1, 1);
return v1;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
/**
* Export image as JPEG bytes with specified quality (0-100).
* @param {number} quality
@@ -156,6 +178,28 @@ export class PhotonImage {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
/**
* Export image as lossless WebP bytes.
* @returns {Uint8Array}
*/
get_bytes_webp() {
try {
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
wasm.photonimage_get_bytes_webp(retptr, this.__wbg_ptr);
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true);
if (r3) {
throw takeObject(r2);
}
var v1 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_export3(r0, r1 * 1, 1);
return v1;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
}
/**
* Get the height of the image.
* @returns {number}
+2 -2
View File
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cd7e6079f999193d10dc7c841d62c31b1e88cdee495b8e5688ee9d1a0252e4c0
size 3436485
oid sha256:651b67f5d05c8391d6e1590c04b5c74cc9d2cc8e3c5d9f7ebe6fd83dd103e99f
size 3718674
+2
View File
@@ -12,7 +12,9 @@ export const has_match: (a: number, b: number, c: number, d: number, e: number,
export const highlight_code: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
export const html_to_markdown: (a: number, b: number, c: number, d: number) => void;
export const photonimage_get_bytes: (a: number, b: number) => void;
export const photonimage_get_bytes_gif: (a: number, b: number) => void;
export const photonimage_get_bytes_jpeg: (a: number, b: number, c: number) => void;
export const photonimage_get_bytes_webp: (a: number, b: number) => void;
export const photonimage_get_height: (a: number) => number;
export const photonimage_get_width: (a: number) => number;
export const photonimage_new_from_byteslice: (a: number, b: number, c: number) => void;