Html画布使用宽高比旋转更大的图像

时间:2017-08-04 14:11:59

标签: javascript html canvas

我有一个代码示例,我将大图像调整为较小的尺寸,画布与图像的大小相匹配。有一个旋转右侧功能,可以旋转画布内部的图像,调整画布大小。我几乎完美地工作但图像只有在原始或颠倒时才是完美尺寸。当图像向左或向右旋转时,我无法获得高度正确的比例。这是我的jsfiddle和代码,它是来自不同小提琴的修改代码。图像仅用作测试。

var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var canvasWidth = 400;
    var canvasHeight;

    var degrees=0;

    var image=document.createElement("img");
    image.onload=function(){
    canvas.width = canvasWidth;
    canvasHeight = 400 / (image.width / image.height);  
    canvas.height = canvasHeight;
    ctx.drawImage(image,0,0,canvas.width,canvas.height);
    }
  

    image.src="https://www.magezinepublishing.com/equipment/images/equipment/Lumix-DMCFZ330-5824/highres/Panasonic-Lumix-FZ330-Wide-P1010001_1438873612.jpg";


     $("#clockwise").click(function(){
     degrees+=90
     if (degrees >= 360) degrees = 0;
     
     if (degrees === 0 || degrees === 180 ) {
         canvas.width = canvasWidth;
         canvas.height = canvasHeight;
     }
     else {
         // swap
         canvas.width = canvasHeight;
         canvas.height = canvasWidth;
     }
     ctx.save();
     // you want to rotate around center of canvas
     ctx.translate(canvas.width/2,canvas.height/2);
    
     ctx.rotate(degrees*Math.PI/180);
     ctx.drawImage(image, -canvas.width*0.5, -canvas.height*0.5, canvas.width, canvas.height);
     ctx.restore();
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" ></canvas><br>
    <button id="clockwise">Rotate right</button>

jsfiddle

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

请记住您旋转图像。在图像绘制调用中使用交换的画布宽度/高度时,您正在更改图像的纵横比。通过计算,旋转的原始图像应该已经适合画布。由此产生的图像也会被拉伸。

enter image description here

使用ctx.drawImage(image, -canvasWidth*0.5, -canvasHeight*0.5, canvasWidth, canvasHeight);

Else说,你想绘制相同的图像,然后用画布调用旋转/翻译它。但是你正在做的是在旋转90°或270°时绘制不同尺寸的拉伸图像然后旋转/平移它。

答案 1 :(得分:1)

以90度为单位旋转图像。

而是使用平移和缩放,您可以通过直接设置转换矩阵来旋转图像。

ctx.setTransform(a,b,c,d,e,f);

参数如下

  • a,b描述像素x轴的方向和大小的矢量
  • c,d描述像素y轴的方向和大小的矢量
  • e,f原点的坐标(其中0,0将是)

所有这些都在画布像素坐标中。默认值为a = 1b =0像素的x轴为1像素,0向下,c = 0d = 1 y轴0像素跨越,1像素向下,{ {1}},e = 0来自左上角。

要将图像顺时针旋转90度,您希望xAxis沿画布向下移动,y轴从右向左移动。原点移动到画布的右上角。

f = 0

当您缩放0.5时,这意味着像素将是一半大小,并且当您绘制图像时,您需要原点以使图像适合图像。

ctx.setTransform(
   0,1, // x axis down
  -1,0  // y axis from left to right
  ctx.canvas.height,  // origin x and y to top right
  0,
)
ctx.drawimage(image,0,0);

您可以为每个额外的轮换

执行相同的操作
// rotate image 90 deg and scale 0.5
ctx.setTransform(
   0,0.5, // x axis down
  -0.5,0  // y axis from left to right
  image.height * 0.5,  // origin x and y to top right
  0,
)
ctx.drawimage(image,0,0);

每次旋转的图像尺寸如下

// rotate 180 scale 0.5
ctx.setTransform(-0.5,0,0,-0.5, image.width * 0.5,image.height * 0.5);
// rotate -90 scale 0.5
ctx.setTransform(0,-0.5,0.5,0, 0,image.width* 0.5);

要将变换恢复为默认值,只需将变换设置为单位矩阵

// for 0deg and 180 deg rotation
canvas.width = image.width * 0.5;
canvas.width = image.height * 0.5;

// for 90deg and -90 deg rotation
canvas.width = image.height * 0.5;
canvas.width = image.width * 0.5;