You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HTML5 Canvas旋转上传图片后出现裁切,如何获取完整图像?

解决Canvas旋转图片后裁切/变形的问题

嘿,我完全懂你遇到的这个头疼问题——旋转后的头像要么被裁切,要么莫名其妙变成方形,核心问题其实出在两个地方:旋转后画布的尺寸没跟上图片的新尺寸,还有drawImage的坐标计算错了。我来帮你把代码改对,顺便解释清楚每个关键点:

核心问题分析

当你把图片旋转270度(也就是逆时针旋转90度)时,图片的宽高会完全互换:比如原本宽400、高600的图片,旋转后实际需要的画布尺寸应该是宽600、高400。但你原来的代码还是用了原图的宽高作为画布尺寸,这就导致一部分内容超出画布被裁切;另外drawImage的偏移参数也没对应旋转后的坐标系统,进一步加剧了裁切问题。

修改后的完整代码

function preview_image(event) { 
    var fileReader = new FileReader(); 
    fileReader.readAsDataURL(event.target.files[0]); 
    fileReader.onload = function(event) { 
        var canvas = document.createElement("canvas"); 
        var context = canvas.getContext("2d"); 
        var image = new Image(); 
        image.src = event.target.result; 
        image.onload = function() { 
            // 关键1:旋转270度后,画布尺寸要互换(原图宽高对调)
            canvas.width = image.height; 
            canvas.height = image.width; 

            // 保存画布状态,准备变换
            context.save(); 
            // 关键2:将坐标原点移到新画布的中心
            context.translate(canvas.width / 2, canvas.height / 2); 
            // 旋转270度(转换为弧度)
            context.rotate(270 * Math.PI / 180); 
            // 关键3:修正drawImage的偏移,让图片中心与画布中心对齐
            // 旋转后,图片的宽高逻辑上已互换,所以偏移用-image.height/2和-image.width/2
            context.drawImage(image, -image.height / 2, -image.width / 2); 
            // 恢复画布原始状态
            context.restore(); 

            // 添加预览图到页面
            $('#img_div').prepend('<img id="main_img" src="' + canvas.toDataURL("image/jpeg", 0.9) + '">'); 
            document.getElementById("img_div").style.display = "inline-block"; 
            document.getElementById("img_div").style.visibility = "visible"; 
        } 
    }; 
}

关键修改点详解

  • 移除冗余代码:删掉了原来无意义的context.drawImage和context.clearRect,刚绘制就清除完全没必要。
  • 适配旋转后的画布尺寸:旋转270度后,图片的宽高会互换,所以把canvas.width设为原图的高度,canvas.height设为原图的宽度,确保画布能容纳下完整的旋转后图片。
  • 修正绘制坐标:旋转后坐标系统已经改变,这时候要让图片中心与画布中心对齐,偏移参数需要用-image.height/2和-image.width/2,而不是原来的-image.width/2重复两次。
  • 优化图片质量:调用toDataURL时添加了质量参数0.9(范围0-1),避免默认生成的JPG图片质量过低。

通用扩展提示

如果以后需要支持其他旋转角度(比如90度、180度),可以参考这个逻辑:

  • 旋转90/270度:画布宽高互换,调整drawImage的偏移参数
  • 旋转180度:画布尺寸不变,偏移参数还是-image.width/2和-image.height/2,只是旋转角度改为Math.PI

这样修改后,旋转后的图片就不会再出现裁切或者变形的问题啦!

内容的提问来源于stack exchange,提问作者donm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:47:15