【问题标题】:How to resize and rotate image simulataneously using canvas如何使用画布同时调整图像大小和旋转图像
【发布时间】:2019-01-02 21:38:14
【问题描述】:

上传前我要调整图片大小和旋转,resize是让图片变小,rotate是为了修正iPhone截取的图片。

这是我正在使用的代码,对于resize,我正在使用较小的画布来重绘图像,对于旋转,我正在使用画布来执行此操作。 问题是,我的图像只显示了源图像的一部分。如何显示全图?

这是源图片

这就是我得到的代码:你可以看到旋转是正确的,但调整大小不正确,它会剪切源图像并只留下一部分。

这就是我想要的。

const img = new Image();
img.src = 'https://i.stack.imgur.com/rzJQD.jpg';
img.onload = e => resize_and_rotate(img, 6);

function resize_and_rotate(img, orientation) {
  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");

  // limit the image to at most 600px width or 900px height.
  let ratio = img.height / img.width;
  if (img.width > 600) {
    canvas.width = 600;
    canvas.height = canvas.width * ratio;
  } else if (img.height > 900) {
    canvas.height = 900;
    canvas.width = canvas.height / ratio;
  }

  let width = canvas.width;
  let height = canvas.height;
  /*
      For iPhone, landscape mode(with home key point to right) is the correct mode, it orientation is 1
      for portrait mode(home key point to bottom), the image will rotate right by 90 degree.
   */
  if (orientation === 6) { // rotate 90 degree.
    // swap canvas width and height.
    canvas.width = height;
    canvas.height = width;

    // move to the center of the canvas
    ctx.translate(canvas.width / 2, canvas.height / 2);

    // rotate the canvas to the specified degrees
    ctx.rotate(0.5 * Math.PI);

    // since the context is rotated, the image will be rotated also
    ctx.drawImage(img, -img.width / 2, -img.height / 2);

  } else if (orientation === 3) { // rotate 180 degree.
    // 180° rotate left
    ctx.translate(canvas.width, canvas.height);
    ctx.rotate(Math.PI);
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  } else if (orientation === 8) { // rotate 90 degree, counter-clockwise.
    canvas.width = height;
    canvas.height = width;

    // move to the center of the canvas
    ctx.translate(canvas.width / 2, canvas.height / 2);

    // rotate the canvas to the specified degrees
    ctx.rotate(-0.5 * Math.PI);

    // since the context is rotated, the image will be rotated also
    ctx.drawImage(img, -img.width / 2, -img.height / 2);
  } else {
    ctx.fillStyle = "#fff";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
  }

  // return base64 data.
//  let base64 = canvas.toDataURL("image/jpeg");
//  return base64;
  // for SO
  document.body.append(canvas);
}
canvas{max-height: 100vh; max-width: 100vw}

如果我删除以下代码,结果是正确的,但它不会调整我的图像大小。画布大小似乎有问题?请帮忙。

 // limit the image to at most 600px width or 900px height.
        let ratio = img.height / img.width;
        if (img.width > 600) {
            canvas.width = 600;
            canvas.height = canvas.width * ratio;
        } else if (img.height > 900) {
            canvas.height = 900;
            canvas.width = canvas.height / ratio;
        }

【问题讨论】:

    标签: html canvas html5-canvas


    【解决方案1】:

    你的问题在于drawImage
    您没有使用足够的参数,也没有使用正确的值。

    在您完成转换 (translate(center); rotate()) 后,您正确地尝试反转平移,以便从左上角按应有的方式绘制图像。但是,您使用图像的原始大小作为 x,y 参数而不是目标参数。

    此外,通过使用 3 参数版本,您可以让 destinationWidthdestinationHeight 成为图像的原始大小,而您需要画布的宽度和高度:

    ctx.drawImage(img, -width / 2, -height / 2, width, height);
    

    const img = new Image();
    img.src = 'https://i.stack.imgur.com/rzJQD.jpg';
    img.onload = e => resize_and_rotate(img, 6);
    
    function resize_and_rotate(img, orientation) {
      let canvas = document.createElement("canvas");
      let ctx = canvas.getContext("2d");
    
      // limit the image to at most 600px width or 900px height.
      let ratio = img.height / img.width;
      if (img.width > 600) {
        canvas.width = 600;
        canvas.height = canvas.width * ratio;
      } else if (img.height > 900) {
        canvas.height = 900;
        canvas.width = canvas.height / ratio;
      }
    
      let width = canvas.width;
      let height = canvas.height;
      /*
          For iPhone, landscape mode(with home key point to right) is the correct mode, it orientation is 1
          for portrait mode(home key point to bottom), the image will rotate right by 90 degree.
       */
      if (orientation === 6) { // rotate 90 degree.
        // swap canvas width and height.
        canvas.width = height;
        canvas.height = width;
    
        // move to the center of the canvas
        ctx.translate(canvas.width / 2, canvas.height / 2);
    
        // rotate the canvas to the specified degrees
        ctx.rotate(0.5 * Math.PI);
    
        // since the context is rotated, the image will be rotated also
        ctx.drawImage(img, -width / 2, -height / 2, width, height);
    
      } else if (orientation === 3) { // rotate 180 degree.
        // 180° rotate left
        ctx.translate(canvas.width, canvas.height);
        ctx.rotate(Math.PI);
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
      } else if (orientation === 8) { // rotate 90 degree, counter-clockwise.
        canvas.width = height;
        canvas.height = width;
    
        // move to the center of the canvas
        ctx.translate(height / 2, width / 2);
    
        // rotate the canvas to the specified degrees
        ctx.rotate(-0.5 * Math.PI);
    
        // since the context is rotated, the image will be rotated also
        ctx.drawImage(img, -width / 2, -height / 2, width, height);
      } else {
        ctx.fillStyle = "#fff";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(img, 0, 0, width, height);
      }
    
      // return base64 data.
    //  let base64 = canvas.toDataURL("image/jpeg");
    //  return base64;
      // for SO
      document.body.append(canvas);
    }
    canvas{max-height: 100vh; max-width: 100vw}

    【讨论】:

    • 你救了我,兄弟!
    猜你喜欢
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2017-08-22
    • 2017-10-19
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 1970-01-01
    相关资源
    最近更新 更多