我有这个简单的canvas
网页,可让用户使用HTML input type file
从相机上传照片。这个想法是让用户在他们的图像上自由绘图。但是,我有一个问题。
在某些设备上,来自相机的图像以错误的方向绘制到画布上,因此我必须为用户提供一个按钮来旋转图像以获得正确方向的图形。
问题在于,在对画布进行变换和旋转以获得正确的方向后,绘图坐标似乎已经过时了。例如,如果我绘制直线水平线,我会在图像旋转一次后获得直线垂直线。我认为问题在于帆布方向已经改变。
那么如何在图像转换和旋转后校正绘图坐标?我的代码在下面..
window.onload = init;
var canvas, ctx, file, fileURL;
var mousePressed = false;
var lastX, lastY;
function init(){
canvas = document.getElementById('myCanvas')
ctx = canvas.getContext('2d')
canvas.addEventListener('mousedown', touchstartHandler, false)
canvas.addEventListener('mousemove', touchmoveHandler, false)
canvas.addEventListener('mouseup', touchendHandler, false)
canvas.addEventListener('mouseleave', touchcancelHandler, false)
}
function touchstartHandler(e){
e.preventDefault()
mousePressed = true;
Draw(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, false);
}
function touchmoveHandler(e){
e.preventDefault()
if (mousePressed) {
Draw(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
}
}
function touchendHandler(e){
e.preventDefault()
if (mousePressed) {
mousePressed = false;
}
}
function touchcancelHandler(e){
e.preventDefault()
if (mousePressed) {
mousePressed = false;
}
}
function Draw(x, y, isDown) {
if (isDown) {
ctx.beginPath();
ctx.strokeStyle = "blue";
ctx.lineWidth = 12;
ctx.lineJoin = "round";
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
}
lastX = x;
lastY = y;
}
<!DOCTYPE html>
<html>
<head>
<title>Portrait</title>
</head>
<body>
<canvas id="myCanvas"></canvas><br/>
<input type="file" onchange="fileUpload(this.files)" id="file-input" capture="camera"><br/><br/>
<button onclick="rotate()">Rotate</button>
<script>
var file, canvas, ctx, image, fileURL;
function fileUpload(files){
file = files[0]
fileURL = URL.createObjectURL(file)
canvas = document.getElementById('myCanvas')
canvas.style.backgroundColor = "blue"
ctx = canvas.getContext('2d')
image = new Image()
image.onload = function() {
canvas.width = 500
canvas.height = (500*this.height)/this.width
ctx.drawImage(image,0,0,canvas.width,canvas.height)
ctx.save();
}
image.src = fileURL
}
function rotate(){
ctx.clearRect(0,0,canvas.width,canvas.height)
ctx.translate(canvas.width/2, canvas.height/2)
ctx.rotate(90*Math.PI/180)
ctx.translate(-canvas.width/2, -canvas.height/2)
ctx.drawImage(image,0,0,canvas.width,canvas.height)
}
</script>
</body>
</html>
答案 0 :(得分:2)
在旋转和翻译之前,您需要save画布状态,然后在转换完成后restore状态。
var file, canvas, ctx, image, fileURL, rotation = 90;
function fileUpload(files) {
file = files[0]
fileURL = URL.createObjectURL(file)
canvas = document.getElementById('myCanvas')
canvas.style.backgroundColor = "blue"
ctx = canvas.getContext('2d')
image = new Image()
image.onload = function() {
canvas.width = 500
canvas.height = (500 * this.height) / this.width
ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
}
image.src = fileURL
}
function rotate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save(); //save canvas state
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(rotation * Math.PI / 180);
ctx.translate(-canvas.width / 2, -canvas.height / 2);
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
rotation += 90;
ctx.restore(); //restore canvas state
}
&#13;
canvas {border: 1px solid red}
&#13;
<canvas id="myCanvas"></canvas>
<br/>
<input type="file" onchange="fileUpload(this.files)" id="file-input" capture="camera">
<br/>
<br/>
<button onclick="rotate()">Rotate</button>
&#13;
答案 1 :(得分:0)
以90度为单位旋转图像的最快方法
ctx.setTransform(
0,1, // direction of x axis
-1,0 // direction of y axis
canvas.width,0 // location in pixels of the origin (0,0)
);
然后绘制图像
ctx.drawImage(image,0,0);
在许多情况下,您可以将转换设置为默认值,而不是使用ctx.restore()
。
ctx.setTransform(1,0,0,1,0,0);
因此旋转90度
ctx.setTransform(0,1,-1,0,canvas.width,0);
ctx.drawImage(image,0,0);
ctx.setTransform(1,0,0,1,0,0);
因此旋转180度
ctx.setTransform(-1,0,0,-1,canvas.width,canvas.height);
ctx.drawImage(image,0,0);
ctx.setTransform(1,0,0,1,0,0);
因此旋转-90度
ctx.setTransform(0,-1,1,0,0,canvas.height);
ctx.drawImage(image,0,0);
ctx.setTransform(1,0,0,1,0,0);