将 ajax arraybuffer 响应绘制到 canvas
Draw ajax arraybuffer response into canvas
你好,我从我的服务器(binay、arraybuffer)请求一个图像,然后我想将该 arraybuffer 转换为可以在任何 canvas 元素上绘制的有效图像数据。
除了由 ajax 请求生成的 imageData 之外,我还有其他 imageData 对象,我在 canvas 上将它们组合在一起(为了展平图像)并生成我的最终图像。但是,上面提到的来自服务器请求的 imageData 会产生纯噪声,我不确定我在创建有效 imageData 时做错了什么。
这是我尝试将 arraybuffer 转换为 imageData 但没有成功的方法。
ImageProcessor.prototype.imageData = function(data, width, height) {
width = width || this.settings.width;
height = height || this.settings.width;
var newData = (data instanceof Uint8ClampedArray) ? data : new Uint8ClampedArray(data);
var imageData = this.ctx.createImageData(width, height);
imageData.data.set(newData);
return imageData;
};
PS:我设法将 arrayBuffer 转换为 b64 图像资源 -URL 然后从中创建图像,然后将图像绘制到 canvas 元素上,但我对这样的解决方案不感兴趣,因为:
我觉得矫枉过正
使用回调
更新
服务器上的图像是.png 文件(RGBA)。
下面是 ajaxTransport 与 jQuery 一起使用,以便对来自服务器的图像进行二进制 - arraybuffer 请求:
$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
// check for conditions and support for blob / arraybuffer response type
if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
{
return {
// create new XMLHttpRequest
send: function(_, callback){
// setup all variables
var xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
// blob or arraybuffer. Default is blob
dataType = options.responseType || "blob",
data = options.data || null;
xhr.addEventListener('load', function(){
var data = {};
data[options.dataType] = xhr.response;
// make callback and send data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
});
xhr.open(type, url, true);
xhr.responseType = dataType;
xhr.send(data);
},
abort: function(){
jqXHR.abort();
}
};
}
});
您可以使用 Blob 和 blob-url 设置为图像源。这比使用 Base-64 和 Data-URI 稍微好一些,因为您不需要将二进制数据转换为字符串,然后再返回(内部)。
数据不能直接设置为文件容器中的ImageData
对象,因为"file"(字节数组)必须先解析、解压、解码和转换。
示例:
var blob = new Blob([arrayBufferHere], {type: "image/png"}); // set proper mime-type
var domURL = self.URL || self.webkitURL || self,
url = domURL.createObjectURL(blob),
img = new Image;
img.onload = function () {
domURL.revokeObjectURL(url); // clean up
// this = image
};
img.src = url;
演示
// load file:
fetch("http://i.imgur.com/rUeQDjE.png", convert, alert);
function convert(buffer) {
var blob = new Blob([buffer], {type: "image/png"});
var domURL = self.URL || self.webkitURL || self,
url = domURL.createObjectURL(blob),
img = new Image;
img.onload = function() {
domURL.revokeObjectURL(url); // clean up
document.body.appendChild(this);
// this = image
};
img.src = url;
}
function fetch(url, callback, error) {
var xhr = new XMLHttpRequest();
try {
xhr.open("GET", url);
xhr.responseType = "arraybuffer";
xhr.onerror = function() {
error("Network error")
};
xhr.onload = function() {
if (xhr.status === 200) callback(xhr.response);
else error(xhr.statusText);
};
xhr.send();
} catch (err) {
error(err.message)
}
}
(可选,您可以使用我的 png-toy 解码为原始位图)
您还可以使用 this library (PNG.js) 解码 PNG 而无需依赖 <img>
。
希望 canvas API 将来能够使用类似于网络音频 API 中的 decodeAudioData 的本机 decodeImageData 方法进行更新。如果没有计划,也许可以在 WHATWG 跟踪器上请求它?
你好,我从我的服务器(binay、arraybuffer)请求一个图像,然后我想将该 arraybuffer 转换为可以在任何 canvas 元素上绘制的有效图像数据。
除了由 ajax 请求生成的 imageData 之外,我还有其他 imageData 对象,我在 canvas 上将它们组合在一起(为了展平图像)并生成我的最终图像。但是,上面提到的来自服务器请求的 imageData 会产生纯噪声,我不确定我在创建有效 imageData 时做错了什么。
这是我尝试将 arraybuffer 转换为 imageData 但没有成功的方法。
ImageProcessor.prototype.imageData = function(data, width, height) {
width = width || this.settings.width;
height = height || this.settings.width;
var newData = (data instanceof Uint8ClampedArray) ? data : new Uint8ClampedArray(data);
var imageData = this.ctx.createImageData(width, height);
imageData.data.set(newData);
return imageData;
};
PS:我设法将 arrayBuffer 转换为 b64 图像资源 -URL 然后从中创建图像,然后将图像绘制到 canvas 元素上,但我对这样的解决方案不感兴趣,因为:
我觉得矫枉过正
使用回调
更新
服务器上的图像是.png 文件(RGBA)。
下面是 ajaxTransport 与 jQuery 一起使用,以便对来自服务器的图像进行二进制 - arraybuffer 请求:
$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
// check for conditions and support for blob / arraybuffer response type
if (window.FormData && ((options.dataType && (options.dataType == 'binary')) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
{
return {
// create new XMLHttpRequest
send: function(_, callback){
// setup all variables
var xhr = new XMLHttpRequest(),
url = options.url,
type = options.type,
// blob or arraybuffer. Default is blob
dataType = options.responseType || "blob",
data = options.data || null;
xhr.addEventListener('load', function(){
var data = {};
data[options.dataType] = xhr.response;
// make callback and send data
callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
});
xhr.open(type, url, true);
xhr.responseType = dataType;
xhr.send(data);
},
abort: function(){
jqXHR.abort();
}
};
}
});
您可以使用 Blob 和 blob-url 设置为图像源。这比使用 Base-64 和 Data-URI 稍微好一些,因为您不需要将二进制数据转换为字符串,然后再返回(内部)。
数据不能直接设置为文件容器中的ImageData
对象,因为"file"(字节数组)必须先解析、解压、解码和转换。
示例:
var blob = new Blob([arrayBufferHere], {type: "image/png"}); // set proper mime-type
var domURL = self.URL || self.webkitURL || self,
url = domURL.createObjectURL(blob),
img = new Image;
img.onload = function () {
domURL.revokeObjectURL(url); // clean up
// this = image
};
img.src = url;
演示
// load file:
fetch("http://i.imgur.com/rUeQDjE.png", convert, alert);
function convert(buffer) {
var blob = new Blob([buffer], {type: "image/png"});
var domURL = self.URL || self.webkitURL || self,
url = domURL.createObjectURL(blob),
img = new Image;
img.onload = function() {
domURL.revokeObjectURL(url); // clean up
document.body.appendChild(this);
// this = image
};
img.src = url;
}
function fetch(url, callback, error) {
var xhr = new XMLHttpRequest();
try {
xhr.open("GET", url);
xhr.responseType = "arraybuffer";
xhr.onerror = function() {
error("Network error")
};
xhr.onload = function() {
if (xhr.status === 200) callback(xhr.response);
else error(xhr.statusText);
};
xhr.send();
} catch (err) {
error(err.message)
}
}
(可选,您可以使用我的 png-toy 解码为原始位图)
您还可以使用 this library (PNG.js) 解码 PNG 而无需依赖 <img>
。
希望 canvas API 将来能够使用类似于网络音频 API 中的 decodeAudioData 的本机 decodeImageData 方法进行更新。如果没有计划,也许可以在 WHATWG 跟踪器上请求它?