使用javascript

时间:2019-03-28 16:39:59

标签: javascript html canvas

我有以下代码,该代码允许用户上传放入画布中的图像,但是一旦绘制完成,我希望用户能够通过单击按钮来旋转图像,但是我不希望这样做不知道如何重新访问图像对象才能旋转画布。下面的代码是有效的:

onFilePicked (e) {
  const files = e.target.files;
  for (let file of files) {
    if(file !== undefined) {
      let image = {
        thumbnail: '/img/spinner.gif'
      };
      this.images.push(image);
      this.loadImage(file, image);
    }
  }
},

loadImage(file, image) {
  const fr = new FileReader();
  fr.readAsDataURL(file);
  fr.addEventListener('load', () => {
    var img = new Image();
    img.src = fr.result;
    img.onload = () => {
      image.thumbnail = this.resizeImage(img, 400, 300);
      image.large = this.resizeImage(img, 1280, 960);
    }        
  })
},

resizeImage(origImg, maxWidth, maxHeight) {
  let scale = 1;
  if (origImg.width > maxWidth) {
    scale = maxWidth / origImg.width;
  }
  if (origImg.height > maxHeight) {
    let scale2 = maxHeight / origImg.height;
    if (scale2 < scale) scale = scale2;
  }

  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");

  canvas.width = origImg.width * scale;
  canvas.height= origImg.height * scale;    
  ctx.drawImage(origImg, 0, 0, canvas.width, canvas.height);
  return canvas.toDataURL("image/jpeg");
},

下面是我构建的用于旋转图像的功能-它的工作原理是,如果我用下面的代码替换resizeImage函数内部的代码,则该图像以正确旋转的方式绘制,但是我不知道如何访问origImg对象以能够在单独的函数中重画画布。

rotateImage(origImg, maxWidth, maxHeight){
  let scale = 1;
  if (origImg.width > maxWidth) {
    scale = maxWidth / origImg.width;
  }
  if (origImg.height > maxHeight) {
    let scale2 = maxHeight / origImg.height;
    if (scale2 < scale) scale = scale2;
  }

  let canvas = document.createElement("canvas");
  let ctx = canvas.getContext("2d");

  canvas.width = origImg.height * scale;
  canvas.height= origImg.width * scale;
  ctx.translate(canvas.width, 0);  
  ctx.rotate(90 * Math.PI / 180);
  ctx.drawImage(origImg, 0, 0, canvas.height, canvas.width);
  return canvas.toDataURL("image/jpeg");
},

按原样运行此功能会触发以下控制台错误:

无法在'CanvasRenderingContext2D'上执行'drawImage':提供的值不是'(CSSImageValue或HTMLImageElement或SVGImageElement或HTMLVideoElement或HTMLCanvasElement或ImageBitmap或OffscreenCanvas)'

如何从resizeImage函数获取/重用origImg对象,以便可以在rotateImage函数中使用它?

2 个答案:

答案 0 :(得分:0)

您可以尝试使用以下代码:

var myCanvas = document.getElementById('my_canvas_id');
var ctx = myCanvas.getContext('2d');
var img = new Image;
img.onload = function(){
  ctx.drawImage(origImg,0,0); // Or at whatever offset you like
};

并应用您的代码insede onimg的onload函数,最后将img源转换为日期URL

根据一个文件选择器和两个按钮尝试此代码。第一个调整图片大小,第二个调整图片大小

function resizeImg()
        {
        
            var oPicker = document.getElementById('avatar');
            var oImage = document.getElementById('imgOut');
            var file = oPicker.files[0];
            const fr = new FileReader();
            fr.readAsDataURL(file);
            fr.addEventListener('load', () => {
                var img = new Image();
                img.src = fr.result;
                img.onload = () => {
                  oImage.thumbnail = this.resizeImage(img, 400, 300);
                  oImage.src = this.resizeImage(img, 1280, 960);
                }        
              })
        }                
        
        function rotateImg()
        {
            var imgOut = document.getElementById('imgOut');
            
            
              let canvas = document.createElement("canvas");
              let ctx = canvas.getContext("2d");
              let scale = 1;
              canvas.width = imgOut.height * scale;
              canvas.height= imgOut.width * scale;
              ctx.translate(canvas.width, 0);  
              ctx.rotate(90 * Math.PI / 180);
              ctx.drawImage(imgOut, 0, 0, canvas.height, canvas.width);
              imgOut.src = canvas.toDataURL("image/jpeg");
              
            
        }
        
        
        function resizeImage(origImg, maxWidth, maxHeight) {
          let scale = 1;
          if (origImg.width > maxWidth) {
            scale = maxWidth / origImg.width;
          }
          if (origImg.height > maxHeight) {
            let scale2 = maxHeight / origImg.height;
            if (scale2 < scale) scale = scale2;
          }

          let canvas = document.createElement("canvas");
          let ctx = canvas.getContext("2d");

          canvas.width = origImg.width * scale;
          canvas.height= origImg.height * scale;    
          ctx.drawImage(origImg, 0, 0, canvas.width, canvas.height);
          return canvas.toDataURL("image/jpeg");
        }
<html>
    <head>
        <title>Test</title>
  </head>
    <body>
        <h1>Image test</h1>
        <img src="" id="imgOut" />
        <label for="avatar">Choose a profile picture:</label>
        <input type="file" id="avatar" name="avatar" accept="image/png, image/jpeg">
        <input type="button" id="resImg" onclick="resizeImg()" value="Resize" />
        <input type="button" id="rotImg" onclick="rotateImg()" value="Rotate" />
        
    </body>
</html>

答案 1 :(得分:0)

onFilePicked()中,您将存储有关图像的内容:

let image = {
  thumbnail: '/img/spinner.gif'
};
this.images.push(image);

,然后在loadImage()中更新相同的对象(当然,其中有一个事件处理程序)

image.thumbnail = this.resizeImage(img, 400, 300);
image.large = this.resizeImage(img, 1280, 960);

可以简单地扩展到

image.original = img;
image.thumbnail = this.resizeImage(img, 400, 300);
image.large = this.resizeImage(img, 1280, 960);

从这一点开始,您的images数组中的对象将有一个original字段,用于存储图像的原始,未调整大小的变体。