HTML Canvas在转换和旋转后重置绘图点

时间:2017-06-29 10:41:53

标签: html canvas html5-canvas

我有这个简单的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>

2 个答案:

答案 0 :(得分:2)

在旋转和翻译之前,您需要save画布状态,然后在转换完成后restore状态。

&#13;
&#13;
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;
&#13;
&#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,180,-90deg

因此旋转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);