canvas.toDataURL() 值改变,即使 canvas 没有改变
canvas.toDataURL() value changing even if canvas didn't change
我一直在研究并尝试编写一个应用程序来获取 HTML5 canvas 元素上的任何图像并将其发送给客户。当尝试使用 canvas.toDataURL() 获取图像、压缩并将其发送回服务器时,客户端有时显示图像,有时不显示发送的内容。首先我认为可能是数据已损坏,但在本地服务器上工作并且有 29/30 损坏的数据对我来说没有意义,所以我试图查看发生了什么并注册了长度base64 图像并注意到它的长度在变化,尽管 canvas 的内容没有变化。为什么会这样?
我写了一个简单的页面,您可以在其中编辑 canvas 内容,方法是在上面绘图,显示发生的情况:
<!DOCTYPE html>
<html>
<head>
<title>Draw</title>
<style>
body{margin:0;}
</style>
<script>
addEventListener("load", Load, false);
var board = undefined;
var ctx = undefined;
var loaded = false;
var mousehold = false;
var mousex = 0;
var mousey = 0;
var lastx = 0;
var lasty = 0;
var firstclick = false;
function Load(e)
{
loaded = true;
board = document.getElementById("board");
ctx = board.getContext("2d");
board.width = window.innerWidth;
board.height = window.innerHeight;
addEventListener("mousedown", function(e)
{
mousehold = true;
}, false);
addEventListener("mouseup", function(e)
{
mousehold = false;
firstclick = false;
}, false);
addEventListener("mousemove", function(e)
{
mousex = e.clientX;
mousey = e.clientY;
// if(mousehold == true) console.log(mousex + " " + mousey);
}, false);
ctx.beginPath();
ctx.lineWidth = 5;
UpdateBoard();
}
function UpdateBoard()
{
if(mousehold == true)
{
if(firstclick == false)
{
lastx = mousex;
lasty = mousey;
firstclick = true;
}
ctx.moveTo(lastx, lasty);
ctx.lineTo(mousex, mousey);
ctx.stroke();
lastx = mousex, lasty = mousey;
}
window.requestAnimationFrame(UpdateBoard);
}
function send()
{
var img = board.toDataURL();
console.log(img.length);
}
</script>
</head>
<body>
<canvas id="board"></canvas>
<button style="right:10px;bottom:10px;position:fixed;z-index:999999;" onclick="send();">Send</button>
</body>
</html>
单击"send" 按钮将在控制台上记录base64 图像长度。如果你在屏幕上画东西,canvas 的内容显然会改变,但如果你停止画画并点击 "send" 按钮几次(不触及 canvas 内容)你会看到它似乎生成了不同的 base64 图像。为什么会这样?是否有可能阻止这种情况的发生?我的应用程序需要不断更新内容(压缩,但我试过不压缩,问题是一样的)。
为了演示这个问题,我上传了一张图片到 imgur:http://imgur.com/a/iQ70T(忽略图片中的错别字)。
感谢您的关注。
发生这种情况的原因是您已将所有事件侦听器附加到 window
对象而不是 canvas(mousedown
,其他的可以在 window) 当您点击发送按钮时,mousedown
也会被注册。
这意味着为每一帧重新绘制最后一条路径,因为 mousehold
将是真实的,累积影响 alpha 通道的抗锯齿像素,因此将改变位图。
修复示例(只需将 mousedown 处理程序附加到 canvas):
addEventListener("load", Load, false);
var board = undefined;
var ctx = undefined;
var loaded = false;
var mousehold = false;
var mousex = 0;
var mousey = 0;
var lastx = 0;
var lasty = 0;
var firstclick = false;
function Load(e) {
loaded = true;
board = document.getElementById("board");
ctx = board.getContext("2d");
board.width = window.innerWidth;
board.height = window.innerHeight;
// this must be at canvas element
board.addEventListener("mousedown", function(e) {
mousehold = true;
}, false);
addEventListener("mouseup", function(e) {
mousehold = false;
firstclick = false;
}, false);
addEventListener("mousemove", function(e) {
mousex = e.clientX;
mousey = e.clientY;
// if(mousehold == true) console.log(mousex + " " + mousey);
}, false);
ctx.beginPath();
ctx.lineWidth = 5;
UpdateBoard();
}
function UpdateBoard() {
if (mousehold == true) {
if (firstclick == false) {
lastx = mousex;
lasty = mousey;
firstclick = true;
}
ctx.moveTo(lastx, lasty);
ctx.lineTo(mousex, mousey);
ctx.stroke();
lastx = mousex, lasty = mousey;
}
window.requestAnimationFrame(UpdateBoard);
}
function send() {
var img = board.toDataURL();
console.log(img.length);
}
body {margin:0}
<canvas id="board"></canvas>
<button style="right:10px;bottom:10px;position:fixed;z-index:999999;" onclick="send();">Send</button>
我一直在研究并尝试编写一个应用程序来获取 HTML5 canvas 元素上的任何图像并将其发送给客户。当尝试使用 canvas.toDataURL() 获取图像、压缩并将其发送回服务器时,客户端有时显示图像,有时不显示发送的内容。首先我认为可能是数据已损坏,但在本地服务器上工作并且有 29/30 损坏的数据对我来说没有意义,所以我试图查看发生了什么并注册了长度base64 图像并注意到它的长度在变化,尽管 canvas 的内容没有变化。为什么会这样?
我写了一个简单的页面,您可以在其中编辑 canvas 内容,方法是在上面绘图,显示发生的情况:
<!DOCTYPE html>
<html>
<head>
<title>Draw</title>
<style>
body{margin:0;}
</style>
<script>
addEventListener("load", Load, false);
var board = undefined;
var ctx = undefined;
var loaded = false;
var mousehold = false;
var mousex = 0;
var mousey = 0;
var lastx = 0;
var lasty = 0;
var firstclick = false;
function Load(e)
{
loaded = true;
board = document.getElementById("board");
ctx = board.getContext("2d");
board.width = window.innerWidth;
board.height = window.innerHeight;
addEventListener("mousedown", function(e)
{
mousehold = true;
}, false);
addEventListener("mouseup", function(e)
{
mousehold = false;
firstclick = false;
}, false);
addEventListener("mousemove", function(e)
{
mousex = e.clientX;
mousey = e.clientY;
// if(mousehold == true) console.log(mousex + " " + mousey);
}, false);
ctx.beginPath();
ctx.lineWidth = 5;
UpdateBoard();
}
function UpdateBoard()
{
if(mousehold == true)
{
if(firstclick == false)
{
lastx = mousex;
lasty = mousey;
firstclick = true;
}
ctx.moveTo(lastx, lasty);
ctx.lineTo(mousex, mousey);
ctx.stroke();
lastx = mousex, lasty = mousey;
}
window.requestAnimationFrame(UpdateBoard);
}
function send()
{
var img = board.toDataURL();
console.log(img.length);
}
</script>
</head>
<body>
<canvas id="board"></canvas>
<button style="right:10px;bottom:10px;position:fixed;z-index:999999;" onclick="send();">Send</button>
</body>
</html>
单击"send" 按钮将在控制台上记录base64 图像长度。如果你在屏幕上画东西,canvas 的内容显然会改变,但如果你停止画画并点击 "send" 按钮几次(不触及 canvas 内容)你会看到它似乎生成了不同的 base64 图像。为什么会这样?是否有可能阻止这种情况的发生?我的应用程序需要不断更新内容(压缩,但我试过不压缩,问题是一样的)。
为了演示这个问题,我上传了一张图片到 imgur:http://imgur.com/a/iQ70T(忽略图片中的错别字)。
感谢您的关注。
发生这种情况的原因是您已将所有事件侦听器附加到 window
对象而不是 canvas(mousedown
,其他的可以在 window) 当您点击发送按钮时,mousedown
也会被注册。
这意味着为每一帧重新绘制最后一条路径,因为 mousehold
将是真实的,累积影响 alpha 通道的抗锯齿像素,因此将改变位图。
修复示例(只需将 mousedown 处理程序附加到 canvas):
addEventListener("load", Load, false);
var board = undefined;
var ctx = undefined;
var loaded = false;
var mousehold = false;
var mousex = 0;
var mousey = 0;
var lastx = 0;
var lasty = 0;
var firstclick = false;
function Load(e) {
loaded = true;
board = document.getElementById("board");
ctx = board.getContext("2d");
board.width = window.innerWidth;
board.height = window.innerHeight;
// this must be at canvas element
board.addEventListener("mousedown", function(e) {
mousehold = true;
}, false);
addEventListener("mouseup", function(e) {
mousehold = false;
firstclick = false;
}, false);
addEventListener("mousemove", function(e) {
mousex = e.clientX;
mousey = e.clientY;
// if(mousehold == true) console.log(mousex + " " + mousey);
}, false);
ctx.beginPath();
ctx.lineWidth = 5;
UpdateBoard();
}
function UpdateBoard() {
if (mousehold == true) {
if (firstclick == false) {
lastx = mousex;
lasty = mousey;
firstclick = true;
}
ctx.moveTo(lastx, lasty);
ctx.lineTo(mousex, mousey);
ctx.stroke();
lastx = mousex, lasty = mousey;
}
window.requestAnimationFrame(UpdateBoard);
}
function send() {
var img = board.toDataURL();
console.log(img.length);
}
body {margin:0}
<canvas id="board"></canvas>
<button style="right:10px;bottom:10px;position:fixed;z-index:999999;" onclick="send();">Send</button>