如何在网络工作者中获取图像宽度和高度?

mpe*_*pen 2 javascript web-worker

这是我的代码:

// process-image.js (web-worker)
self.addEventListener('message', ev => {
    const {id,file} = ev.data;

    const reader = new FileReader();
    reader.onload = ev => {
        const imageFile = new Image(); // <-- error is here
        imageFile.src = ev.target.result;

        imageFile.onload = () => {
            const fit = makeFit(imageFile);

            self.postMessage({
                id,
                file: {
                    src: ev.target.result,
                    width: fit.width,
                    height: fit.height,
                }
            })
        }
    };

    reader.readAsDataURL(file);
});
Run Code Online (Sandbox Code Playgroud)

这在主 UI 线程中运行良好,但显然我无法访问Image网络工作者的内部。具体错误是:

Uncaught ReferenceError: Image is not defined at FileReader.reader.onload (process-image.js:12)

有没有另一种方法来获取图像的宽度和高度?

我想支持尽可能多的文件类型,但如果有某种库可以做到这一点并且可以在网络工作者中运行,那么现在只有 JPG 就足够了。


这是 UI 线程中的相关部分:

// some-react-component.js
    componentDidMount() {
        this.worker = new ImageWorker();
        this.worker.addEventListener('message', ev => {
            const {id, file} = ev.data;

            this.setState(({files}) => {
                files = files.update(id, img => ({
                    ...img,
                    ...file,
                }))

                const withWidths = files.filter(f => f.width);
                const avgImgWidth = withWidths.reduce((acc, img) => acc + img.width, 0) / withWidths.size;

                return {files, avgImgWidth};
            });
        });
    }


    onDrop = ev => {
        ev.preventDefault();


        Array.prototype.forEach.call(ev.dataTransfer.files, file => {

            const id = shortid();
            this.worker.postMessage({id, file});

            const img = {
                id,
                width: null,
                height: null,
                src: null,
                name: file.name,
            }
            this.setState(({files}) => ({files: files.set(id, img)}));
        });
    }
Run Code Online (Sandbox Code Playgroud)

这里唯一值得注意的是它id只是一个随机的 UUID,并且file是一个File. 我正在将整个事情传递给网络工作者,以便我可以在那里进行所有处理。

Pin*_*niH 5

我认为可能有一个更简单的解决方案:

https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/createImageBitmap

我设法在不使用 FileReader 的情况下获得了大小:

http://jsfiddle.net/hL1Ljkmv/2/

var response = `self.addEventListener('message', async ev => {
    const {id,file} = ev.data;
    console.log('received data');
    let image = await self.createImageBitmap(file);
    console.log(image);
});`;

const blob = new Blob([response], {type: 'application/javascript'});
const worker = new Worker(URL.createObjectURL(blob));

const input = document.querySelector('#file-input');
input.addEventListener('change', (e) => {
  worker.postMessage({file: input.files[0], id: 1})
});
Run Code Online (Sandbox Code Playgroud)