JavaScript:在没有画布的情况下获取ImageData

问题描述 投票:0回答:4
是否可以从不在画布上、而是在 DOM 树中其他位置的图像中获取一个

ImageData

 对象作为普通 
<img>

如果是,怎么办?

javascript html canvas
4个回答
83
投票
您必须创建一个内存画布,然后在该画布上绘制图像:

var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); var img = document.getElementById('myimg'); canvas.width = img.width; canvas.height = img.height; context.drawImage(img, 0, 0 ); var myData = context.getImageData(0, 0, img.width, img.height);

但是如果图像来自另一个域,这将不起作用。如果您无法控制服务器,这是一个无法绕过的安全限制(请注意,如果您使用 file:// 打开 html 文件,您将有很多额外的限制,请使用 http://)


25
投票
正如已经暗示的,canvas 提供了创建 ImageData 对象的唯一解决方案。

如果你真的反对使用canvas元素来加载图像数据(也许我们正在谈论LTE IE8),你总是可以考虑使用图像对象的src位置来解析base64图像数据

http://blog.calyptus.eu/seb/2009/05/png-parser-in-javascript/

这很困难,但如果你必须的话,可能会以这种方式将图像解析为数组。

https://github.com/devongovett/png.js/blob/master/png.js

这向您展示了如何使用 xhr 请求加载数据并解析 png 数据。在内部,它使用画布来做其他一些事情,但您感兴趣的子集是免费的。对于您感兴趣的每种图像格式,您需要遵循类似的实现。

我应该提到,图像像素读取限制在安全性方面是相同的。无论有或没有画布,您将永远无法读取来自第三方的像素。 XMLHTTPRequest 将与跨域策略的治理绑定。这可以防止脚本窃取第三方内容,其中包括可能包含敏感用户信息的图像。

如果您需要读取第三方域上的图像(不需要身份验证即可查看),您应该在您的域上运行图像代理服务器,该服务器允许您请求同一域上的图像。如果您需要解决这个问题,首先将图像数据作为 json 数组提供可能会更容易。


11
投票
如果您使用网络工作者,您可以使用

OffscreenCanvas

 作为 
document.createElement('canvas')
 的替代品

var response = await fetch(imageUrl); var fileBlob = await response.blob(); var bitmap = await createImageBitmap(fileBlob); var canvas = new OffscreenCanvas(bitmap.width, bitmap.height); var context = canvas.getContext('2d'); context.drawImage(bitmap, 0, 0); var myData = context.getImageData(0, 0, bitmap.width, bitmap.height);

请注意,对 OffscreenCanvas 的支持是有限的:

https://caniuse.com/#feat=offscreencanvas


0
投票
您必须手动解码文件中的数据。您需要源 URL 来获取原始文件,然后使用正确的解码器来获取原始像素数据。

https://github.com/photopea/UPNG.js - PNG 编码器/解码器 - 需要 Pako https://github.com/nodeca/pako - 我使用它进行编码和解码以绕过画布,因为某些浏览器添加了防指纹功能,这会破坏需要精确值的高度图。

fetch(url) .then(response => response.arrayBuffer()) .then((buffer) => { const pngImg = UPNG.decode(buffer) const rgbaArr = new Uint8ClampedArray(UPNG.toRGBA8(pngImg)[0]) const imageData = new ImageData( rgbaArr, pngImg.width, pngImg.height ); })

https://github.com/jpeg-js/jpeg-js - JPEG 编码器/解码器 - 尚未测试

对于 webp,几年前我用 emscripten 构建了自己的 libwebp 解码器,但现在也许有一个定制的 JS 实现。全部在 github 中。

© www.soinside.com 2019 - 2024. All rights reserved.