JavaScript使用Canvas调整上传图片:固定宽度等比例自适应高度
图片上传固定宽度等比例自适应高度实现方案
现有代码修复方案
你当前的代码将canvas高度写死为380px,会导致图片拉伸变形,只需要按比例计算高度即可。
计算逻辑:以固定宽度500px为基准,计算缩放比例 = 目标宽度 / 原图宽度,再用原图高度 × 缩放比例得到自适应的canvas高度。
修改后的JS代码:
$(".upload-button").on('click', function() { $(".file-upload").click(); }); var fileReader = new FileReader(); fileReader.onload = function(event) { var image = new Image(); image.onload = function() { var canvas = document.createElement("canvas"); var context = canvas.getContext("2d"); // 固定宽度500px,按比例计算高度 const targetWidth = 500; const scaleRatio = targetWidth / image.width; const targetHeight = image.height * scaleRatio; canvas.width = targetWidth; canvas.height = targetHeight; context.drawImage(image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height ); document.getElementById("upload-preview").src = canvas.toDataURL(); } image.src = event.target.result; }; var uploadImage = function() { var uploadImage = document.getElementById("upload-Image"); if (uploadImage.files.length === 0) { return; } var uploadFile = document.getElementById("upload-Image").files[0]; fileReader.readAsDataURL(uploadFile); }
配套HTML代码无需修改:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="upload-button" id="imageresize"><img id="upload-preview" class="profile-pic" src="add-image.png" /></div> <input id="upload-Image" class="file-upload" type="file" name="my_file" onchange="uploadImage();" accept="image/*">
其他更优实现方案
- 纯CSS自适应方案:如果不需要前端对图片做压缩、裁剪等预处理,直接给预览图片添加样式即可实现等比例适配,不需要额外JS逻辑:
#upload-preview { width: 500px; height: auto; /* 可额外添加最大高度限制避免超长图占用过多空间 */ max-height: 800px; object-fit: contain; }
- 优化版canvas缩放方案:增加小图适配逻辑,避免原图宽度小于500px时被强制放大导致模糊:
// 放在image.onload逻辑内 const targetWidth = image.width > 500 ? 500 : image.width; const scaleRatio = targetWidth / image.width; const targetHeight = image.height * scaleRatio;
- 固定容器裁剪方案:如果需要预览区域固定宽高、图片不变形,可直接使用CSS
object-fit: cover实现居中裁剪,不需要canvas处理:
.upload-button { width: 500px; height: 380px; overflow: hidden; } #upload-preview { width: 100%; height: 100%; object-fit: cover; }
内容的提问来源于stack exchange,提问作者Noufal Binu
相关产品推荐
相关产品推荐

