使用vite将原始图像数据导入到脚本中

问题描述 投票:0回答:2

根据Vite文档,可以将文件作为原始数据字符串导入。

在一个精简的项目中,我不仅需要使用 URL,还需要使用整个图像数据。 因此,我尝试

import image from "@/assets/image.png?raw"
。 然而,无论我尝试什么,我都无法将其转换为
Uint8Array
。我尝试过使用
string.charCodeAt(0)
string.codePointAt(0)
和各种其他东西。 我希望第一个字节是
137, 80, 78, 71, 13, 10, 26, 10
,因为那是 PNG header,但它总是返回为
253, 80, 78, 71, 13, 10, 26, 10
。这些差异贯穿整个字符串。

我不知道它是什么编码,因此不知道如何将其再次解码为图像数据。我之前尝试过使用

fetch()
,但由于我的来源使用
Basic-Auth
,这也不起作用(凭据会因用户而异,我想避免让他们在其他地方再次输入它 - 我使用
https://user:[email protected] 
作为 URL 符号)。

import image from "@/assets/image.png?raw";

let data = Uint8Array.from([..image].map(x => x.codePointAt(0)));
console.log(data);
// [253, 80, 78, 71, 13, 10, 26, 10, ...]

如何在不使用 fetch 之类的情况下将实际图像数据获取到我的脚本中? 格式几乎可以是任何东西,我将它用作

Uint8Array
base64
字符串,并且可以在两者之间进行转换。我还可以从
Blob
/
File
进行转换。

javascript png svelte vite
2个回答
5
投票

原始加载器似乎不适合二进制数据。当我尝试时,我最终在数据中出现了替换字符 (

)。

您可以轻松编写自己的插件,根据需要对图像进行编码,例如作为十六进制字符串:

/** @type {import('vite').Plugin} */
const hexLoader = {
    name: 'hex-loader',
    transform(code, id) {
        const [path, query] = id.split('?');
        if (query != 'raw-hex')
            return null;

        const data = fs.readFileSync(path);
        const hex = data.toString('hex');

        return `export default '${hex}';`;
    }
};

可以在vite配置中添加,例如

const config = {
    plugins: [hexLoader, sveltekit()],
    // ...
}

然后您可以使用

path/file.png?raw-hex
导入并转换数据


0
投票

如何正确导入资源有点令人困惑,但我相信使用 url 是正确的选择。如此处所述 https://vitejs.dev/guide/assets.html#importing-asset-as-url 这些将内联为八位字节流或静态资产,名称中的哈希值会发生变化,允许使用长缓存过期时间。

虽然我也尝试使用如上所示的十六进制字符串,但我发现它使导入的二进制文件的大小增加了一倍。所以我现在使用:

import binUrl from './file.bin?url'


   ...
   const bin = new Uint8Array(await (await fetch(binUrl)).arrayBuffer())
   ...
© www.soinside.com 2019 - 2024. All rights reserved.