我有这个代码用于从不同的服务器URL创建画布图像
function getBase64Image(imageUri) {
var canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
var img = new Image();
img.src = imageUri;
img.crossOrigin = "Anonymous";
img.onload = function() {
canvas.width = this.width;
canvas.height = this.height;
ctx.drawImage(img, 0, 0, this.width, this.height);
var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL("image/png");
document.getElementById("dummyhiddenField").value = dataURL;
};
}
Run Code Online (Sandbox Code Playgroud)
我试图从服务器获取图像并将其画布网址设置为隐藏字段,但仅适用于本地图像
根据stackoverflow的其他答案我设置crossOrigin = "Anonymous"哪些不起作用也无法从服务器设置访问源,必须管理localscript的所有内容
谢谢
mar*_*rkE 14
以下是跨域内容如何影响html5画布以及如何在适用于跨域内容的安全限制内工作的更新视图
今天(2016年1月)更新很有用,因为有几种新的(ish)方法可以将跨域图像绘制到画布而不会污染画布.
在html5画布上绘制跨域内容会导致它"被污染"
您可以在画布上从另一个域绘制图像,它将显示在画布上.从另一个域访问资源称为"跨源资源共享" - 通常简称为"CORS".
绘制CORS内容(f.ex:images)会导致画布出于安全原因而被"污染".
如果画布被污染,则无法使用这些画布和上下文方法:
context.getImageData 获取画布上的像素数据canvas.toDataURL 将画布导出为图像你不能"欺骗"画布违反其CORS安全限制 - 希望你甚至不想尝试!但是,您可以通过满足CORS安全限制来绘制跨原始图像而不会污染画布.
处理图像的"通常"(和最简单)方式,因此它们不会污染画布:
将您的图像放在与网页相同的域中.您可以使用多个物理服务器来提供内容,但图像域必须与创建画布的html代码(或javascript代码)相同.CORS限制得到满足,画布不受污染.
在自己的计算机上进行开发时有关CORS的注意事项
解决方案#1(!):您可以在开发计算机上安装Web服务器,并从一个域提供网页文件(.html,.js等)和图像文件(.png,.jpg等).
您的开发计算机的文件夹被声明为不同的域.因此,从本地磁盘上的子目录中绘制图像将违反CORS限制,因为不同的本地文件夹是不同的域.
解决方案#2:在进行开发时,您可以将网页文件和图像文件放在桌面上,图像将声明在同一个域中,并且您的画布不会受到污染.
当图像在不同的域上时,满足CORS限制
解决方案#3:您可以在画布上使用跨域图像而不会污染它.为此,您必须满足以下要求:
客户端:图像对象必须crossOrigin设置属性以允许跨源内容.可以在html元素标记内或javascript中设置此属性.启用设置是"匿名"和"使用凭据".
Serverside:必须将服务器配置为返回标头,指示响应包含授权内容.
根据配置,可能需要多个响应标头:
Access-Control-Allow-Origin将返回匿名授权(*)或将根据请求返回特定授权.
Access-Control-Allow-Credentials 如果身份验证需要其他信息(如cookie),则需要.
Access-Control-Expose-Headers 使客户端能够访问其他响应信息.
在服务器上启用跨域请求可能很复杂,尤其是在提供基于客户端角色授权的内容时.有关启动配置的其他信息,请访问:http://enable-cors.org/index.html.
使用允许匿名访问其图像的跨域图像主机
解决方案#4:某些公共映像主机允许您上载将以CORS兼容方式提供给客户端的映像.几个例子是:imgur和dropbox.Stackoverflow图像托管在Imgur上.
以下是如何以符合CORS的方式在Dropbox.com上提供图像的示例:
这是使用javascript从Dropbox获取符合CORS的图像对象的示例代码:
var img=new Image();
img.crossOrigin='anonymous';
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sun.png";
img.onload=start;
function start(){
context.drawImage(img,0,0);
// The canvas is not tainted so
// the following both work without errors
var url=canvas.toDataURL();
var imageData=context.getImageData(0,0,100,100);
}
Run Code Online (Sandbox Code Playgroud)
新(ish):通过让客户端用户同意来满足CORS
CORS安全限制旨在阻止坏人秘密接收您的信息,同时让您不知情.
直到最近,浏览器依靠客户端 - 服务器配置来满足安全性要求.最近,如果用户肯定地参与决定正在使用什么内容,则浏览器已经开始允许跨源内容.
解决方案#5: Chrome和Firefox现在允许客户端用户访问right click the canvas & save the canvas as an image.这是手动等效于canvas.toDataURL用于创建图像对象并将该图像对象保存到本地驱动器.CORS很满意,因为用户决定画布内容是否适合保存到本地驱动器,并且肯定地右键单击以启动下载过程.
解决方案#6:您可以使用an input element, type='file'让客户端用户选择图像.用户甚至可以选择互联网URL(http:// ..).同样,CORS很满意,因为用户参与了选择过程.
这是示例代码,显示如何使用输入监听用户选择图像:
// canvas vars
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");
// define max resulting image width,height (after resizing)
var maxW=100;
var maxH=100;
// listen for user to select files
var input = document.getElementById('input');
input.addEventListener('change', handleFiles);
function handleFiles(e) {
var img = new Image;
img.onload = function(){
var iw=img.width;
var ih=img.height;
// scale down, if necessary
if(iw>maxW || ih>maxH){
var scale=Math.min((maxW/iw),(maxH/ih));
iw*=scale;
ih*=scale
}
// set canvas width/height to scaled size
canvas.width=iw;
canvas.height=ih;
// draw+scale the img onto the canvas
ctx.drawImage(img,0,0,iw,ih);
// create a jpeg URL (with medium quality to save "weight")
var jpg=canvas.toDataURL('image/jpeg',0.60);
// In Demo: add the jpg to the window
// In production, accumulate jpg's & send to server
$('<img />',{src:jpg}).appendTo('body');
}
// In Demo: Just process the first selected file
// In production: process all selected files
img.src = URL.createObjectURL(e.target.files[0]);
}Run Code Online (Sandbox Code Playgroud)
body{ background-color: ivory; }
#canvas{border:1px solid red;}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>You can even enter a web URI (http://...)</h4>
<input type="file" id="input"/><br>Run Code Online (Sandbox Code Playgroud)
解决方案#7:您可以使用新的(ish)FileReader让用户选择要在画布上绘制的图像.
// dropDiv event handlers
var dropDiv=document.getElementById("dropDiv");
dropDiv.addEventListener("dragenter", handleDragEnter, false);
dropDiv.addEventListener("dragover", handleDragOver, false);
dropDiv.addEventListener("drop", handleDrop, false);
//
function handleDragEnter(e) {
e.stopPropagation();
e.preventDefault();
}
//
function handleDragOver(e) {
e.stopPropagation();
e.preventDefault();
}
//
function handleDrop(e) {
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
handleFiles(files);
}
//
function handleFiles(files) {
for (var i=0;i<files.length;i++) {
var file = files[i];
var imageType = /image.*/;
if (!file.type.match(imageType)) {
continue;
}
var img = document.createElement("img");
img.classList.add("obj");
img.file = file;
preview.appendChild(img);
var reader=new FileReader();
reader.onload=(function(aImg){
return function(e) {
aImg.onload=function(){
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");
canvas.width=aImg.width;
canvas.height=aImg.height;
ctx.drawImage(aImg,0,0);
document.body.appendChild(canvas);
}
// e.target.result is a dataURL for the image
aImg.src = e.target.result;
};
})(img);
reader.readAsDataURL(file);
} // end for
} // end handleFiles
function calcNewAspect(imgWidth, imgHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth/imgWidth,maxHeight/imgHeight);
return {width:imgWidth*ratio,height:imgHeight*ratio };
}Run Code Online (Sandbox Code Playgroud)
body{ background-color: ivory; }
canvas{border:1px solid red;}
#dropDiv{border:1px solid blue; width:300px;height:300px;}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag 1+ image(s) from desktop to blue dropDiv.</h4>
<div id="dropDiv"></div>
<div id="preview"></div>Run Code Online (Sandbox Code Playgroud)
未完待续...
此更新中可能需要包含更多信息位.请随时评论我的心不在焉,我会继续更新.:-)