如何将旋转后的 canvas 元素保存到文件中
How to save a rotated canvas element to a file
我正在尝试旋转大图像并将其另存为文件。由于图像尺寸较大,我尝试了几种失败的方法。 (OpenCV、Paint Shop Pro 等)。
所以,我正在尝试用 javascript 来做到这一点。我可以将图像绘制到旋转的 canvas 上(这有效),但是当我尝试将 canvas 保存到文件时,旋转丢失了。发生这种情况是有道理的,但想了解如何在保存之前 capture/extract canvas 的旋转状态?
客户代码:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function initPage() {
var imageObj = new Image();
imageObj.onload = function() {
// Draw onto rotated canvas
var canvas = document.getElementById('mapCanvas');
context = canvas.getContext('2d');
context.drawImage(imageObj, 0, 0);
// Save image as png
var dt = canvas.toDataURL('image/png');
$.ajax({
type: "POST",
url: "savePNG.php?file=FN617_ROT",
data: {
imgBase64: dt
}
}).done(function(o) {
console.log('saved');
});
};
imageObj.src = 'FN617.png';
}
</script>
<style>
body {
margin: 0;
padding: 0;
}
#mapCanvas {
transform-origin:center center;
transform: rotate(-32.5deg);
}
</style>
</head>
<body onload="initPage();">
<canvas id="mapCanvas" width="9600" height="7200"></canvas>
</body>
</html>
服务器代码:
<?php
$base64 = str_replace('data:image/png;base64,', '', $_REQUEST['imgBase64']);
$data = base64_decode($base64);
file_put_contents(dirname(__FILE__)."/". $_GET['file'].".png", $data);
?>
您可以使用 localStorage
执行此操作,但出于安全原因不能使用文件。
当您捕获 canvas 时,您捕获的是位图,而不是元素。 CSS 仅影响元素 - 与普通图像一样,旋转它实际上不会以任何方式改变原始图像。
为了正确执行此操作,请先删除 CSS 旋转。
然后使用上下文的变换方法应用旋转。这里注意 CSS 默认情况下围绕中心旋转。左上角旋转的canvas不是这样,所以我们需要先平移。
步骤如下:
// translate to center where the rotation will take place:
context.translate(context.canvas.width * 0.5, context.canvas.height * 0.5);
// rotate (uses radians)
context.rotate = -32.5 * 180 / Math.PI;
// translate back as image is drawn from (0,0)
context.translate(-context.canvas.width * 0.5, -context.canvas.height * 0.5);
// draw image
context.drawImage(imageObj, 0, 0);
可选,如果图像与 canvas 的大小不符,则使用图像的大小进行反向翻译。
context.translate(context.canvas.width * 0.5, context.canvas.height * 0.5);
context.rotate = -32.5 * 180 / Math.PI;
context.drawImage(imageObj, -imageObj.width * 0.5, -imageObj.height * 0.5);
现在您可以拍摄 canvas 旋转的图像。
请注意,此大小的 canvas 可能无法在所有浏览器中使用,如果可以,它可能不允许您捕获它的数据 uri,因为某些浏览器对其大小有限制。只是要记住的事情..
我正在尝试旋转大图像并将其另存为文件。由于图像尺寸较大,我尝试了几种失败的方法。 (OpenCV、Paint Shop Pro 等)。
所以,我正在尝试用 javascript 来做到这一点。我可以将图像绘制到旋转的 canvas 上(这有效),但是当我尝试将 canvas 保存到文件时,旋转丢失了。发生这种情况是有道理的,但想了解如何在保存之前 capture/extract canvas 的旋转状态?
客户代码:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>
function initPage() {
var imageObj = new Image();
imageObj.onload = function() {
// Draw onto rotated canvas
var canvas = document.getElementById('mapCanvas');
context = canvas.getContext('2d');
context.drawImage(imageObj, 0, 0);
// Save image as png
var dt = canvas.toDataURL('image/png');
$.ajax({
type: "POST",
url: "savePNG.php?file=FN617_ROT",
data: {
imgBase64: dt
}
}).done(function(o) {
console.log('saved');
});
};
imageObj.src = 'FN617.png';
}
</script>
<style>
body {
margin: 0;
padding: 0;
}
#mapCanvas {
transform-origin:center center;
transform: rotate(-32.5deg);
}
</style>
</head>
<body onload="initPage();">
<canvas id="mapCanvas" width="9600" height="7200"></canvas>
</body>
</html>
服务器代码:
<?php
$base64 = str_replace('data:image/png;base64,', '', $_REQUEST['imgBase64']);
$data = base64_decode($base64);
file_put_contents(dirname(__FILE__)."/". $_GET['file'].".png", $data);
?>
您可以使用 localStorage
执行此操作,但出于安全原因不能使用文件。
当您捕获 canvas 时,您捕获的是位图,而不是元素。 CSS 仅影响元素 - 与普通图像一样,旋转它实际上不会以任何方式改变原始图像。
为了正确执行此操作,请先删除 CSS 旋转。
然后使用上下文的变换方法应用旋转。这里注意 CSS 默认情况下围绕中心旋转。左上角旋转的canvas不是这样,所以我们需要先平移。
步骤如下:
// translate to center where the rotation will take place:
context.translate(context.canvas.width * 0.5, context.canvas.height * 0.5);
// rotate (uses radians)
context.rotate = -32.5 * 180 / Math.PI;
// translate back as image is drawn from (0,0)
context.translate(-context.canvas.width * 0.5, -context.canvas.height * 0.5);
// draw image
context.drawImage(imageObj, 0, 0);
可选,如果图像与 canvas 的大小不符,则使用图像的大小进行反向翻译。
context.translate(context.canvas.width * 0.5, context.canvas.height * 0.5);
context.rotate = -32.5 * 180 / Math.PI;
context.drawImage(imageObj, -imageObj.width * 0.5, -imageObj.height * 0.5);
现在您可以拍摄 canvas 旋转的图像。
请注意,此大小的 canvas 可能无法在所有浏览器中使用,如果可以,它可能不允许您捕获它的数据 uri,因为某些浏览器对其大小有限制。只是要记住的事情..