使用 javascript 旋转动态画布图像



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

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 or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or 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 的加载功能,最后将 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>

由于您在存储有关图像的某些内容的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字段,用于存储图像的原始、未调整大小的变体。

最新更新