我有一个带有画布的网站,我通过要求访问者通过上传按钮上传图片来加载图片。我知道跨源问题所以我拍摄了图片,我使用此插件通过ajax上传:jQuery Form Plugin 然后我在base64中提取图像数据,然后将其发送到画布以将图像加载到它。通过这个过程,我希望避免交叉原始数据问题,但它似乎适用于某些浏览器,而不适用于mac中的其他浏览器,例如我无法执行' getImageData' on' CanvasRenderingContext2D' :Canvas已经被跨源数据所吸引。对此有任何帮助。
感谢。
图片上传的HTML代码是:
<form id="ajax_form" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<input id="upload-input" name="file" class="file" type="file">
</form>
Javascript函数通过ajax处理上传并将图像插入到画布中:
function Editor(canvas, options) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d');
this.valid = false;
this.options = options || {};
this.enabled = true;
this.translate = {x: 0, y: 0, dx: 0, dy: 0};
this.imageRotationPoint = {x: 0, y: 0};
this.scale = 1;
this.scaleExtra = 1;
this.rotate = 0;
this.rotateExtra = 0;
// Currently being rotated
this.inRotation = false;
// Set up the initial event handlers
this.mousedown = Editor.handleMouseDown.bind(this);
this.mouseup = Editor.handleMouseUp.bind(this);
this.mousemove = Editor.handleMouseMove.bind(this);
this.canvas.addEventListener('mousedown', this.mousedown);
this.canvas.addEventListener('touchstart', this.mousedown);
// Handle touch events
var that = this;
this.imgrotate = 0;
var pinchRotateImg = this.canvas;
Transform(pinchRotateImg);
var initScale = 1;
var currentRotation = this.imgrotate;
new AlloyFinger(pinchRotateImg, {
rotate: function (evt) {
currentRotation += evt.angle;
that.inRotation = true;
that.rotate = currentRotation;
that.valid = false;
},
multipointStart: function () {
initScale = pinchRotateImg.scaleX;
},
pinch: function (evt) {
var scale = initScale * evt.zoom;
if (scale > 4) {
scale = 4;
}
if (scale < 0.25){
scale = 0.25;
}
that.scaleExtra = scale;
that.valid = false;
},
pressMove: function (evt) {
that.inRotation = false;
evt.preventDefault();
}
});
this.initialSetup();
setInterval(function () {
that.draw();
}, 30);
};
Editor.prototype.getTheFace = function () {
var w = this.canvas.width;
var h = this.canvas.height;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
canvas.width = w;
canvas.height = h;
ctx.clearRect(0, 0, w, h);
// Position the image
ctx.save();
var img = this.options.image;
ctx.translate(this.translate.x + this.translate.dx, this.translate.y + this.translate.dy);
ctx.scale(this.scale * this.scaleExtra, this.scale * this.scaleExtra);
ctx.rotate((this.rotate + this.rotateExtra) * Math.PI / 180);
// Draw the background image
ctx.drawImage(img, this.imageRotationPoint.x, this.imageRotationPoint.y, img.width, img.height);
// Reset the state
ctx.restore();
ctx.globalCompositeOperation = 'destination-out';
// Create a new canvas with the template
var canvas2 = document.createElement('canvas');
var ctx2 = canvas2.getContext('2d');
canvas2.width = w;
canvas2.height = h;
ctx2.clearRect(0, 0, w, h);
ctx2.drawImage(this.options.template, 0, 0, w, h);
// Remove the line in the middle
ctx2.clearRect(555, 630, 400, 5);
// Cut the face out
ctx.drawImage(canvas2, 0, 0, w, h);
// Cut out the face part of the image, and put it on a separate canvas
var cut = ctx.getImageData(550, 458, 410, 450);
var canvasFace = document.createElement('canvas');
var ctxFace = canvasFace.getContext('2d');
canvasFace.width = 410;
canvasFace.height = 450;
ctxFace.putImageData(cut, 0, 0);
return canvasFace.toDataURL();
};
// Handle uploading files
$('#upload-input').on('change', function () {
processFiles(this.files);
});
function processFiles(files) {
for (var i = 0, len = files.length; i < len; ++i) {
var file = files[i];
// Only process images
if (file.type.match(/^image\//)) {
var options = {
url: '/upload',
type: 'post',
success: afterSuccess
};
$("#ajax_form").ajaxSubmit(options);
}
}
}
function afterSuccess(response) {
var img = new Image();
img.onload = function () {
editor.updateImage(img);
},
img.src = response.dataURL;
}
PHP上传脚本:
public function upload() {
$this->upload->do_upload('file');//This is codeignitor upload library
$b64str = base64_encode(file_get_contents($this->upload->data('file_name')));
$dataURL = "data:".$this->upload->data('file_type').";base64,".$b64str;
$this->output->set_content_type('application/json')->set_output(json_encode(array('dataURL' => $dataURL)));
}