是否可以从不在画布上的图像中获取ImageData
对象,而将DOM树中的其他位置作为普通<img>
?
如果是,怎么样?
答案 0 :(得分:51)
您必须创建一个内存画布,然后在此画布上绘制图像:
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://)
答案 1 :(得分:16)
正如已经暗示的那样,canvas提供了创建ImageData对象的唯一解决方案。
如果您真的反对使用canvas元素加载图像数据(也许我们正在谈论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数组提供可能会更容易。
答案 2 :(得分:2)
如果您使用的是网络工作者,则可以使用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