我尝试将一些 JS 库与 ServiceWorker 一起使用,而不访问 Node.JS 文件系统功能。原来的库导出结果也是一样的
Import * as fs from 'fs'
...
JsLib.export(result, fs.createWriteStream("res.pdf"))
我需要相同的导出,但导出到字节数组,没有文件系统。我以同样的方式创建了数组
const Out = (Array as any).create("byte", mysize)
如果我用测试数据手动填充这个字节数组,我的算法可以进一步正常工作。
但我不明白如何正确创建与 Node.JS 创建的相同的流,但在内存中,在我的“Out”数组中。
MDN 中有一些使用 WritableStream 的示例,但我不确定这些示例与此任务有何关系。也许有像
JsLib.export(result, ...Out)
或者这个解决方案没有模拟fs.createWriteStream?直接使用扩展语法是不可能的“扩展参数必须具有元组类型或传递给剩余参数”。但如何正确解决这个任务呢?
更新。这是对 @l3l_aze 的回答,进行了非常基本的测试,不幸的是,这个解决方案不起作用。
正如我上面所说,我不了解 TS,所以这只是 NodeJS/vanilla JS。强烈建议我花几个小时来研究这个问题,因为它可能无法正确关闭流,而且显然没有包含错误处理。
输出是 PNG 格式的红色方块。为了直观地确认测试,我复制了输出并使用 VSCode Hex Editor 扩展将其粘贴到现有的
file.png
中,并选择了 base64 选项。然后必须从我必须填充的先前数据中删除(Del,而不是 Backspace)剩余字节,以便十六进制编辑器允许粘贴。哈哈。
'use strict'
import * as PImage from 'pureimage'
import Stream from 'stream'
const width = 32
const height = 32
const img1 = PImage.make(width, height)
const ctx = img1.getContext('2d')
ctx.fillStyle = 'red'
ctx.fillRect(0, 0, width, height)
const pngData = []
const dest = new Stream()
dest.writable = true
dest.write = function (data) {
for (let i = 0; i < data.length; i++) {
dest.emit('data', data[i])
}
}
// Act like a passThrough stream; in one ear and out the other.
dest.on('data', (chunk) => {
pngData.push(chunk)
})
dest.on('end', () => {})
// For
// https://github.com/joshmarinacci/node-pureimage/blob/6775bc3dedfd4247c0ee11382e1aebdf2703ca45/src/image.ts#L57
dest.end = function () {
dest.emit('finish')
}
dest.close = function () {
dest.emit('close')
}
function assert (a, b) {
if (a !== b) {
throw new Error(`${a} !== ${b}`)
} else {
return true
}
}
const buf = await PImage.encodePNGToStream(img1, dest).then(() => {
return new Uint8Array(pngData)
})
if (assert(buf[0], 0x89) &&
assert(buf[1], 0x50) &&
assert(buf[2], 0x4e) &&
assert(buf[3], 0x47)) {
console.log('buffer contains png header')
const ascii = Array.from(buf).map((b) => String.fromCharCode(b))
const b64 = btoa(ascii.join(''))
console.log(b64)
// iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAklEQVR4AewaftIAAABBSURBVMXBAQEAAAiDMKR/5xuD7QYjJDGJSUxiEpOYxCQmMYlJTGISk5jEJCYxiUlMYhKTmMQkJjGJSUxiEpOYxB4w4wI+EhsQ6
AAAAABJRU5ErkJggg==
}