【问题标题】:In which format should I pass image from Rust to JS?我应该以哪种格式将图像从 Rust 传递给 JS?
【发布时间】:2021-12-21 21:35:02
【问题描述】:

我正在尝试将图像从 JS 传递给 Rust,对其进行处理并从 Rust 返回给 JS。请帮助我了解我应该以哪种格式从 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.newImage.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 返回的 blob 不正确。在我用 Rust 处理我的图像之前,它具有正确的 jpeg 文件签名:[255、216、255,...]。但处理后变成了 [162, 162, 152, ...]。我认为我应该尝试在其他东西上更改 to_rgb8 方法,但我不明白为什么。你能帮我解释一下我做错了什么吗?

编辑:当我调用 decode 方法时发现签名发生了变化,但我仍然不知道为什么。

【问题讨论】:

标签: javascript image-processing rust webassembly


【解决方案1】:

decode 方法采用 JPEG 文件并将原始像素作为未压缩的内存块返回。换句话说,[162, 162, 152...] 表示右上角像素的值 red=162,green=162,blue=152。您可以使用ImageData 或通过使用image::codecs::jpeg::JpegEncoder.encodesave_buffer_with_format 方法对数据进行编码,从原始字节数据制作图像。有关更多信息,您可以阅读此issue

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 2023-03-26
    • 1970-01-01
    • 2020-03-29
    • 2021-12-07
    • 2021-09-04
    • 1970-01-01
    相关资源
    最近更新 更多