使用javascript旋转动态画布图像

使用javascript旋转动态画布图像,javascript,html,canvas,Javascript,Html,Canvas,我有下面的代码,允许用户上传一个图像,将其放入画布,但一旦它被绘制,我希望用户能够通过点击按钮来旋转图像,但我不知道如何重新访问图像对象以旋转画布。下面的代码是有效的: onFilePicked (e) { const files = e.target.files; for (let file of files) { if(file !== undefined) { let image = { thumbnail: '/img/spinner.gif'

我有下面的代码,允许用户上传一个图像,将其放入画布,但一旦它被绘制,我希望用户能够通过点击按钮来旋转图像,但我不知道如何重新访问图像对象以旋转画布。下面的代码是有效的:

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");
},
onFilePicked(e){
const files=e.target.files;
for(让文件中的文件){
如果(文件!==未定义){
让图像={
缩略图:'/img/spinner.gif'
};
这个.images.push(image);
this.loadImage(文件、图像);
}
}
},
loadImage(文件、图像){
const fr=new FileReader();
fr.readAsDataURL(文件);
fr.addEventListener('load',()=>{
var img=新图像();
img.src=fr.result;
img.onload=()=>{
image.缩略图=此.resizeImage(img,400300);
image.large=this.resizeImage(img,1280960);
}        
})
},
调整图像大小(原始、最大宽度、最大高度){
设标度=1;
如果(原始宽度>最大宽度){
比例=最大宽度/初始宽度;
}
如果(原始高度>最大高度){
设scale2=maxHeight/origImg.height;
如果(scale2
下面是我为旋转图像而构建的函数——它的工作原理是,如果我用下面的代码替换resizeImage函数中的代码,则图像是以正确旋转的方式绘制的,但我不知道如何访问Origim对象,以便能够在单独的函数中重新绘制画布

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");
},
rotateImage(原点、最大宽度、最大高度){
设标度=1;
如果(原始宽度>最大宽度){
比例=最大宽度/初始宽度;
}
如果(原始高度>最大高度){
设scale2=maxHeight/origImg.height;
如果(scale2
按原样运行此函数会触发以下控制台错误:

未能在“CanvasRenderingContext2D”上执行“drawImage”:提供的值不是类型“(CSSImageValue或HTMLImageElement或SVGImageElement或HTMLVideoElement或HtmlCanvaElement或ImageBitmap或OffscreenCanvas)”


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

您可以尝试以下代码:

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
};
并应用img的代码inside onload函数,最后将img源转换为最新URL

试试这段代码,基于一个文件选择器,两个按钮。第一个用于调整图像大小,第二个用于保存图像

函数resizeImg()
{
var oPicker=document.getElementById('avatar');
var oImage=document.getElementById('imgOut');
var file=oPicker.files[0];
const fr=new FileReader();
fr.readAsDataURL(文件);
fr.addEventListener('load',()=>{
var img=新图像();
img.src=fr.result;
img.onload=()=>{
oImage.thumboil=this.resizeImage(img,400300);
oImage.src=this.resizeImage(img,1280960);
}        
})
}                
函数rotateImg()
{
var imgOut=document.getElementById('imgOut');
让canvas=document.createElement(“canvas”);
设ctx=canvas.getContext(“2d”);
设标度=1;
canvas.width=imgOut.height*比例;
canvas.height=imgOut.width*比例;
ctx.translate(canvas.width,0);
ctx.旋转(90*Math.PI/180);
ctx.drawImage(imgOut,0,0,canvas.height,canvas.width);
imgOut.src=canvas.toDataURL(“image/jpeg”);
}
函数大小图像(原始、最大宽度、最大高度){
设标度=1;
如果(原始宽度>最大宽度){
比例=最大宽度/初始宽度;
}
如果(原始高度>最大高度){
设scale2=maxHeight/origImg.height;
如果(scale2

试验
图像测试
选择个人资料图片:

由于您在
onFilePicked()
中有一部分存储了有关图像的信息:

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

它可以简单地扩展到

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

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

我不知道如何访问origImg对象,以便能够在单独的函数中重新绘制画布。-和什么分开?您可能还想显示不起作用的东西,因为这是需要修复的。与resizeImage函数分离。rotateImage函数中的代码仅在
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);