我有一个问题.toDataURL()
的大帆布。 我希望在一个enconde base64
和解码的PHP文件,但如果我有一个大的帆布strDataURI
变量是空的。
我的代码:
var strDataURI = canvas.toDataURL();
strDataURI = strDataURI.substr(22, strDataURI.length);
$.post("save.php",
{
str: strDataURI
};
是否有任何替代.toDataURL()
或某种方式来改变大小限制?
谢谢。
我不知道是否有限制画布的尺寸,但是数据的网址还依赖于浏览器的限制: 数据URL大小限制 。
你可以尝试使用Node.js的+节点帆布(服务器端)来重新创建画布。 我一直在使用这些创建从画布元素可打印图像,并使用toDataURL到目前为止没有任何问题/限制。
您是否使用了fabric.js库? 我注意到你在他们的论坛上张贴的。 Fabric.js可以在Node.js的使用并且具有toDataURLWithMultiplier方法,其中缩放画布/上下文允许你改变dataurl图像尺寸。 您可以检查法源代码,看看如何做到这一点。
编辑:
由于您使用fabric.js我会建议使用Node.js的处理服务器上的画布图像处理。 你会发现如何在Node.js的使用fabric.js更多信息在这里 。
下面是如何使用Node.js和表达一个简单的服务器:
var express = require('express'),
fs = require('fs'),
fabric = require('fabric').fabric,
app = express(),
port = 3000;
var allowCrossDomain = function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.configure(function() {
app.use(express.bodyParser());
app.use(allowCrossDomain);
});
app.options('/', function(req, res) {
res.send(200);
});
app.post('/', function(req, res) {
var canvas = fabric.createCanvasForNode(req.body.width, req.body.height);
console.log('> Loading JSON ...');
canvas.loadFromJSON(req.body.json, function() {
canvas.renderAll();
console.log('> Getting PNG data ... (this can take a while)');
var dataUrl = canvas.toDataURLWithMultiplier('png', req.body.multiplier),
data = dataUrl.replace(/^data:image\/png;base64,/, '');
console.log('> Saving PNG to file ...');
var filePath = __dirname + '/test.png';
fs.writeFile(filePath, data, 'base64', function(err) {
if (err) {
console.log('! Error saving PNG: ' + err);
res.json(200, { error: 'Error saving PNG: ' + err });
} else {
console.log('> PNG file saved to: ' + filePath);
res.json(200, { success: 'PNG file saved to: ' + filePath });
}
});
});
});
app.listen(port);
console.log('> Server listening on port ' + port);
当服务器正在运行,你可以将数据发送给它( postData
)。 服务器期待json
, width
和height
,以重新创建画布,和一个multiplier
来缩放数据的URL的图像。 客户端代码会是这个样子:
var postData = {
json: canvas.toJSON(),
width: canvas.getWidth(),
height: canvas.getHeight(),
multiplier: 2
};
$.ajax({
url: 'http://localhost:3000',
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(postData),
dataType: 'json',
success: function(data) {
console.log(data);
},
error: function(err) {
console.log(err);
}
});
你应该首先考虑这一点:上传的大小是有限的。 该限制取决于浏览器,操作系统和服务器环境。 你可以看看这篇文章: http://www.motobit.com/help/scptutl/pa98.htm
一般来说,你可以尝试这样的事情:首先,我们需要一个函数来dataURI转换为二进制大对象:
function convertDataURItoBlob(dataURI) {
'use strict'
var byteString,
mimestring
if(dataURI.split(',')[0].indexOf('base64') !== -1 ) {
byteString = atob(dataURI.split(',')[1])
} else {
byteString = decodeURI(dataURI.split(',')[1])
}
mimestring = dataURI.split(',')[0].split(':')[1].split(';')[0]
var content = new Array();
for (var i = 0; i < byteString.length; i++) {
content[i] = byteString.charCodeAt(i)
}
var rawContent = new Uint8Array(content),
returnBlob = new Blob([rawContent], {type: mimestring})
return returnBlob;
}
和明年的文件上传功能,透过XMLHttpRequest2:
function upload(blob) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/yourServerEndPoint', true);
xhr.onload = function(e) { ... };
xhr.send(blob);
}
现在,你可以通过你的strDataURI
的第一功能,然后上传与第二函数的文件。
您可以在XMLHttpRequest2中从深层次看这里: http://www.html5rocks.com/en/tutorials/file/xhr2/和对这里的BLOB构造: https://developer.mozilla.org/en-US/docs / DOM /斑点
你总是可以只打破图像向上成较小的部分,并保存这些个人,这可能不是一个坏主意呢。 基本上,你有一个功能,就是像
var largeCanvas = document.getElementById('yourGiantCanvas').getContext('2d'),
slice = document.createElement('canvas').getContext('2d');
slice.canvas.width = 1000;
slice.canvas.height = 1000;
for (var y=0; y < canvas.height; y+=1000){
for (var x=0; x < canvas.width; x+=1000){
slice.clearRect(0, 0, slice.canvas.width, slice.canvas.height);
slice.drawImage(largeCanvas.canvas, x, y, 1000, 1000, 0, 0, 1000, 1000);
var imagePiece = slice.canvas.toDataURL();
//Now just save the imagePiece however you normally were planning to
//and you can build the image again using these slices. You can create
//a much better user experience this way too.
}
}
已经更新了代码到画布上分割成更小的画布对象。 作品不错,并增加了一个跟踪器还:
这允许上传过程的跟踪和整体我认为是更好的为用户。 我使用PHP在稍后阶段归队。
它避免了帆布/浏览器等的大小的问题
我的第一篇所以希望它可以帮助!
//传递类型的文件名
function sliceCanvas(type, canvasId){
var largeCanvas = document.getElementById(canvasId).getContext('2d');
var slice = document.createElement('canvas').getContext('2d');
var baseSize = 500;
fileH = largeCanvas.canvas.height / baseSize;
fileW = largeCanvas.canvas.width / baseSize;
slice.canvas.width = baseSize;
slice.canvas.height = baseSize;
count = 1;
numFiles = Math.ceil(fileH) * Math.ceil(fileW);
for (var y=0; y < largeCanvas.canvas.height; y+=baseSize){
for (var x=0; x < largeCanvas.canvas.width; x+=baseSize){
slice.clearRect(0, 0, slice.canvas.width, slice.canvas.height);
slice.drawImage(largeCanvas.canvas, x, y, baseSize, baseSize, 0, 0, baseSize, baseSize);
var imagePiece = slice.canvas.toDataURL();
typeFinal = type + count;
exportSlice(typeFinal, imagePiece, numFiles);
count++;
}
}
}
阿贾克斯上传:
function exportSlice(type, dataURL, fileNum){
percent = 0;
percentComplete = 0;
$.ajax({
type: "POST",
url: YourServerSideFiletoSave,
data: {image: dataURL, type: type}
})
.done(function( response ) {
console.log(response);
percent++;
percentComplete = Math.ceil(Number(percent/fileNum*100));
return true;
})
.fail(function(response) {
console.log("Image FAILED");
console.log(response);
return false;
})
.always(function(response) {
console.log( "Always");
});
}