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

JavaScript如何从Blob获取上传图片的原始宽高尺寸

图片上传获取原始宽高异常解决方案

问题核心原因

直接读取imageFile宽高返回undefined,是因为File对象只是本地文件的句柄引用,本身不存储图片解码后的像素尺寸信息;读取页面img元素拿到90*90的错误尺寸,是因为取到的是CSS渲染后的布局尺寸,不是图片原始像素值,同时复用受CSS约束的页面img元素作为drawImage的源,会导致canvas只能读到渲染后的低分辨率内容。

可行修复方案

  • 读取图片原始尺寸必须用Image元素的naturalWidth和naturalHeight属性,这两个属性返回值永远对应图片文件的真实像素宽高,完全不受CSS缩放影响。
  • 优先创建脱离文档流的临时Image对象解析本地文件,不要直接复用被CSS约束的页面内img元素做源数据读取,避免样式干扰。
  • 用URL.createObjectURL()生成本地文件的Blob引用加载图片,相比FileReader转base64的方案性能更好,处理大尺寸原图时无额外编码开销。
  • 用完Blob URL后记得手动调用URL.revokeObjectURL()释放内存,避免内存泄漏。

修正后可直接运行的代码

let imgInput = document.getElementById('id_photo');
imgInput.addEventListener('change', function (e) {
    if (!e.target.files) return;
    for (let i = 0; i < e.target.files.length; i++) {
        const imageFile = e.target.files[i];
        const blobURL = URL.createObjectURL(imageFile);
        // 创建临时Image对象,不插入DOM,不受页面CSS影响
        const tempImg = new Image();

        tempImg.onload = function () {
            // 直接读取原始像素尺寸,不受任何样式干扰
            const originWidth = tempImg.naturalWidth;
            const originHeight = tempImg.naturalHeight;

            // 基于原始宽高计算缩放后的目标尺寸
            const [targetWidth, targetHeight] = resizeImage({
                width: originWidth,
                height: originHeight
            });

            const canvas = document.createElement("canvas");
            canvas.width = targetWidth;
            canvas.height = targetHeight;
            const ctx = canvas.getContext("2d");
            // 用临时Image对象绘制,能拿到完整原始像素
            ctx.drawImage(tempImg, 0, 0, targetWidth, targetHeight);

            // 此处编写转base64、后续业务逻辑
            // const resultBase64 = canvas.toDataURL('image/jpeg', 0.9);

            // 释放Blob URL占用的内存
            URL.revokeObjectURL(blobURL);
        }

        tempImg.onerror = function () {
            // 处理图片加载失败场景
            URL.revokeObjectURL(blobURL);
        }

        tempImg.src = blobURL;
    }
});

补充说明

如果不想创建临时Image对象,坚持复用页面上已有的img元素,只需要在img的onload回调里,把读取尺寸的逻辑改成取img.naturalWidth和img.naturalHeight,drawImage传入的img虽然被CSS缩放,但只要传对原始尺寸对应的目标宽高,canvas依然可以绘制出完整分辨率的内容,不会被CSS渲染尺寸影响。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 18:54:32