我应该以哪种格式将图像从 Rust 传递到 JS?
In which format should I pass image from Rust to JS?
我正在尝试将图像从 JS 传递到 Rust,对其进行处理,然后 return 从 Rust 返回到 JS。请帮助我了解我应该使用哪种格式 return 来自 Rust 的图像。
我的 JS 代码是这样的:
import { Image } from "image_processing";
const input = document.getElementById('image-input')
const image_canvas = document.getElementById('image-canvas')
input.addEventListener('change', async (event) => {
const buffer = await event.target.files[0].arrayBuffer();
const view = new Uint8Array(buffer);
const image = Image.new(view);
console.log('xxx1', view);
const imageBlob = image.get_image_blob();
console.log('xxx2', imageBlob);
const blob = new Blob(imageBlob, { type: 'image/jpeg'});
console.log('xxx3', blob);
image_canvas.width = image.get_width();
image_canvas.height = image.get_height();
const imageBitmap = await createImageBitmap(blob, 0, 0, image_canvas.width, image_canvas.height);
const context = image_canvas.getContext('2d');
context.drawImage(imageBitmap, 0, 0);
});
而 Rust Image.new
和 Image.get_image_blob
函数看起来像这样:
#[wasm_bindgen]
impl Image {
pub fn new(image_blob: Vec<u8>) -> Image {
let reader = Reader::new(io::Cursor::new(image_blob))
.with_guessed_format()
.expect("Cursor io never fails");
let extension = match reader.format() {
Some(extension) => extension,
None => panic!("Can't guess image extension")
};
let width;
let height;
let image = match reader.decode() {
Ok(image) => {
let (w, h) = image.dimensions();
width = w;
height = h;
image
},
Err(error) => {
panic!("Can't get image: {}", error)
}
};
Image {
image,
width,
height,
extension,
}
}
.
.
.
pub fn get_image_blob(&self) -> Vec<u8> {
match self.extension {
x if x == ImageFormat::Png => self.image.to_rgba8().to_vec(),
_ => self.image.to_rgb8().to_vec()
}
}
}
当我试图在浏览器控制台中处理 jpeg 图像时,我得到了这个:
看来我从 get_image_blob
得到的 returning blob 不正确。在我用 Rust 处理我的图像之前,它有正确的 jpeg 文件签名:[255, 216, 255, ...]。但是处理后变成了[162, 162, 152, ...]。我假设我应该尝试在其他东西上更改 to_rgb8
方法,但我不明白为什么。你能帮我解释一下我做错了什么吗?
编辑:事实证明当我调用 decode
方法时签名发生了变化,但我仍然不知道为什么。
解码方法采用 JPEG 文件和 returns 原始像素作为未压缩的内存块。换句话说,[162, 162, 152...] 表示右上角的像素值红色=162,绿色=162,蓝色=152。您可以使用 ImageData or by encoding that data with help of image::codecs::jpeg::JpegEncoder.encode or save_buffer_with_format methods. For more information you can read this issue.
从原始字节数据制作图像
我正在尝试将图像从 JS 传递到 Rust,对其进行处理,然后 return 从 Rust 返回到 JS。请帮助我了解我应该使用哪种格式 return 来自 Rust 的图像。
我的 JS 代码是这样的:
import { Image } from "image_processing";
const input = document.getElementById('image-input')
const image_canvas = document.getElementById('image-canvas')
input.addEventListener('change', async (event) => {
const buffer = await event.target.files[0].arrayBuffer();
const view = new Uint8Array(buffer);
const image = Image.new(view);
console.log('xxx1', view);
const imageBlob = image.get_image_blob();
console.log('xxx2', imageBlob);
const blob = new Blob(imageBlob, { type: 'image/jpeg'});
console.log('xxx3', blob);
image_canvas.width = image.get_width();
image_canvas.height = image.get_height();
const imageBitmap = await createImageBitmap(blob, 0, 0, image_canvas.width, image_canvas.height);
const context = image_canvas.getContext('2d');
context.drawImage(imageBitmap, 0, 0);
});
而 Rust Image.new
和 Image.get_image_blob
函数看起来像这样:
#[wasm_bindgen]
impl Image {
pub fn new(image_blob: Vec<u8>) -> Image {
let reader = Reader::new(io::Cursor::new(image_blob))
.with_guessed_format()
.expect("Cursor io never fails");
let extension = match reader.format() {
Some(extension) => extension,
None => panic!("Can't guess image extension")
};
let width;
let height;
let image = match reader.decode() {
Ok(image) => {
let (w, h) = image.dimensions();
width = w;
height = h;
image
},
Err(error) => {
panic!("Can't get image: {}", error)
}
};
Image {
image,
width,
height,
extension,
}
}
.
.
.
pub fn get_image_blob(&self) -> Vec<u8> {
match self.extension {
x if x == ImageFormat::Png => self.image.to_rgba8().to_vec(),
_ => self.image.to_rgb8().to_vec()
}
}
}
当我试图在浏览器控制台中处理 jpeg 图像时,我得到了这个:
看来我从 get_image_blob
得到的 returning blob 不正确。在我用 Rust 处理我的图像之前,它有正确的 jpeg 文件签名:[255, 216, 255, ...]。但是处理后变成了[162, 162, 152, ...]。我假设我应该尝试在其他东西上更改 to_rgb8
方法,但我不明白为什么。你能帮我解释一下我做错了什么吗?
编辑:事实证明当我调用 decode
方法时签名发生了变化,但我仍然不知道为什么。
解码方法采用 JPEG 文件和 returns 原始像素作为未压缩的内存块。换句话说,[162, 162, 152...] 表示右上角的像素值红色=162,绿色=162,蓝色=152。您可以使用 ImageData or by encoding that data with help of image::codecs::jpeg::JpegEncoder.encode or save_buffer_with_format methods. For more information you can read this issue.
从原始字节数据制作图像