【问题标题】:Get file size, image width and height before upload上传前获取文件大小、图片宽度和高度
【发布时间】:2012-09-16 06:07:41
【问题描述】:

如何在上传到我的网站之前使用 jQuery 或 JavaScript 获取文件大小、图像高度和宽度?

【问题讨论】:

标签: javascript jquery html dimensions image-size


【解决方案1】:

通过信息数据预览上传多张图片

使用 HTML5 和 File API

使用URL API 的示例

图片来源为URL representing the Blob object
<img src="blob:null/026cceb9-edr4-4281-babb-b56cbf759a3d">

const EL_browse  = document.getElementById('browse');
const EL_preview = document.getElementById('preview');

const readImage  = file => {
  if ( !(/^image\/(png|jpe?g|gif)$/).test(file.type) )
    return EL_preview.insertAdjacentHTML('beforeend', `Unsupported format ${file.type}: ${file.name}<br>`);

  const img = new Image();
  img.addEventListener('load', () => {
    EL_preview.appendChild(img);
    EL_preview.insertAdjacentHTML('beforeend', `<div>${file.name} ${img.width}×${img.height} ${file.type} ${Math.round(file.size/1024)}KB<div>`);
    window.URL.revokeObjectURL(img.src); // Free some memory
  });
  img.src = window.URL.createObjectURL(file);
}

EL_browse.addEventListener('change', ev => {
  EL_preview.innerHTML = ''; // Remove old images and data
  const files = ev.target.files;
  if (!files || !files[0]) return alert('File upload not supported');
  [...files].forEach( readImage );
});
#preview img { max-height: 100px; }
<input id="browse" type="file" multiple>
<div id="preview"></div>

使用FileReader API 的示例

如果您需要长 Base64 编码数据字符串的图像源
&lt;img src="data:image/png;base64,iVBORw0KGg... ...lF/++TkSuQmCC="&gt;

const EL_browse  = document.getElementById('browse');
const EL_preview = document.getElementById('preview');

const readImage = file => {
  if ( !(/^image\/(png|jpe?g|gif)$/).test(file.type) )
    return EL_preview.insertAdjacentHTML('beforeend', `<div>Unsupported format ${file.type}: ${file.name}</div>`);

  const reader = new FileReader();
  reader.addEventListener('load', () => {
    const img  = new Image();
    img.addEventListener('load', () => {
      EL_preview.appendChild(img);
      EL_preview.insertAdjacentHTML('beforeend', `<div>${file.name} ${img.width}×${img.height} ${file.type} ${Math.round(file.size/1024)}KB</div>`);
    });
    img.src = reader.result;
  });
  reader.readAsDataURL(file);  
};

EL_browse.addEventListener('change', ev => {
  EL_preview.innerHTML = ''; // Clear Preview
  const files = ev.target.files;
  if (!files || !files[0]) return alert('File upload not supported');
  [...files].forEach( readImage );
});
#preview img { max-height: 100px; }
<input id="browse" type="file"  multiple>
<div id="preview"></div>
  

【讨论】:

  • @SMC caniuse.com/fileapi 最近才支持文件 API。我去看看
  • 当 i 的值在回调函数 reader.onload 中被警告时,它显示一个随机增量!例如对于 4 个文件,警报值为 0 3 2 1 。谁能解释一下?
  • @freerunner 您的文件大小不同,因此不会同时加载。
  • 遗憾的是,这需要加载图像两次。如果我们可以将宽度和高度作为文件属性,如文件类型,那就更好了。
【解决方案2】:

Demo

不确定是不是你想要的,只是简单的例子:

var input = document.getElementById('input');

input.addEventListener("change", function() {
    var file  = this.files[0];
    var img = new Image();

    img.onload = function() {
        var sizes = {
            width:this.width,
            height: this.height
        };
        URL.revokeObjectURL(this.src);

        console.log('onload: sizes', sizes);
        console.log('onload: this', this);
    }

    var objectURL = URL.createObjectURL(file);

    console.log('change: file', file);
    console.log('change: objectURL', objectURL);
    img.src = objectURL;
});

【讨论】:

    【解决方案3】:

    如果你可以使用 jQuery 验证插件,你可以这样做:

    HTML:

    <input type="file" name="photo" id="photoInput" />
    

    JavaScript:

    $.validator.addMethod('imagedim', function(value, element, param) {
      var _URL = window.URL;
            var  img;
            if ((element = this.files[0])) {
                img = new Image();
                img.onload = function () {
                    console.log("Width:" + this.width + "   Height: " + this.height);//this will give you image width and height and you can easily validate here....
    
                    return this.width >= param
                };
                img.src = _URL.createObjectURL(element);
            }
    });
    

    函数作为 ab onload 函数传递。

    代码取自here

    【讨论】:

    • 'this' in this'files[0] 没有任何价值。这必须更改为 element.files[0] 才能工作。
    • 如何实现多文件选择?
    【解决方案4】:

    这是一个纯 JavaScript 示例,它选择一个图像文件,显示它,循环遍历图像属性,然后将画布中的图像重新调整大小为 IMG 标记,并将调整大小的图像类型显式设置为 jpeg。

    如果您在画布标签中右键单击顶部图像,然后选择“文件另存为”,它将默认为 PNG 格式。如果您右键单击,并将文件另存为下部图像,它将默认为 JPEG 格式。任何宽度超过 400 像素的文件都会缩小到 400 像素的宽度,并且高度与原始文件成比例。

    HTML

    <form class='frmUpload'>
      <input name="picOneUpload" type="file" accept="image/*" onchange="picUpload(this.files[0])" >
    </form>
    
    <canvas id="cnvsForFormat" width="400" height="266" style="border:1px solid #c3c3c3"></canvas>
    <div id='allImgProperties' style="display:inline"></div>
    
    <div id='imgTwoForJPG'></div>
    

    脚本

    <script>
    
    window.picUpload = function(frmData) {
      console.log("picUpload ran: " + frmData);
    
    var allObjtProperties = '';
    for (objProprty in frmData) {
        console.log(objProprty + " : " + frmData[objProprty]);
        allObjtProperties = allObjtProperties + "<span>" + objProprty + ": " + frmData[objProprty] + ", </span>";
    };
    
    document.getElementById('allImgProperties').innerHTML = allObjtProperties;
    
    var cnvs=document.getElementById("cnvsForFormat");
    console.log("cnvs: " + cnvs);
    var ctx=cnvs.getContext("2d");
    
    var img = new Image;
    img.src = URL.createObjectURL(frmData);
    
    console.log('img: ' + img);
    
    img.onload = function() {
      var picWidth = this.width;
      var picHeight = this.height;
    
      var wdthHghtRatio = picHeight/picWidth;
      console.log('wdthHghtRatio: ' + wdthHghtRatio);
    
      if (Number(picWidth) > 400) {
        var newHeight = Math.round(Number(400) * wdthHghtRatio);
      } else {
        return false;
      };
    
        document.getElementById('cnvsForFormat').height = newHeight;
        console.log('width: 400  h: ' + newHeight);
        //You must change the width and height settings in order to decrease the image size, but
        //it needs to be proportional to the original dimensions.
        console.log('This is BEFORE the DRAW IMAGE');
        ctx.drawImage(img,0,0, 400, newHeight);
    
        console.log('THIS IS AFTER THE DRAW IMAGE!');
    
        //Even if original image is jpeg, getting data out of the canvas will default to png if not specified
        var canvasToDtaUrl = cnvs.toDataURL("image/jpeg");
        //The type and size of the image in this new IMG tag will be JPEG, and possibly much smaller in size
        document.getElementById('imgTwoForJPG').innerHTML = "<img src='" + canvasToDtaUrl + "'>";
    };
    };
    
    </script>
    

    这是一个 jsFiddle:

    jsFiddle Pick, display, get properties, and Re-size an image file

    在 jsFiddle 中,右键单击顶部图像(画布)不会为您提供与右键单击 IMG 标记中的底部图像相同的保存选项。

    【讨论】:

      【解决方案5】:

      据我所知,没有一种简单的方法可以做到这一点,因为 Javascript/JQuery 无法访问本地文件系统。 html 5 中有一些新功能允许您检查某些元数据,例如文件大小,但我不确定您是否真的可以获得图像尺寸。

      这是我发现的一篇关于 html 5 功能的文章,以及涉及使用 ActiveX 控件的 IE 解决方法。 http://jquerybyexample.blogspot.com/2012/03/how-to-check-file-size-before-uploading.html

      【讨论】:

        【解决方案6】:

        所以我开始尝试 FileReader API 必须提供的不同功能,并可以创建带有 DATA URL 的 IMG 标记。

        缺点:不能在手机上使用,但在谷歌浏览器上可以正常使用。

        $('input').change(function() {
            
            var fr = new FileReader;
            
            fr.onload = function() {
                var img = new Image;
                
                img.onload = function() { 
        //I loaded the image and have complete control over all attributes, like width and src, which is the purpose of filereader.
                    $.ajax({url: img.src, async: false, success: function(result){
                    		$("#result").html("READING IMAGE, PLEASE WAIT...")
                    		$("#result").html("<img src='" + img.src + "' />");
                        console.log("Finished reading Image");
                		}});
                };
                
                img.src = fr.result;
            };
            
            fr.readAsDataURL(this.files[0]);
            
        });
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <input type="file" accept="image/*" capture="camera">
        <div id='result'>Please choose a file to view it. <br/>(Tested successfully on Chrome - 100% SUCCESS RATE)</div>

        (在 http://jsfiddle.net/eD2Ez/530/ 的 jsfiddle 上查看此内容)
        (请参阅我添加到 http://jsfiddle.net/eD2Ez/ 的原始 jsfiddle)

        【讨论】:

          【解决方案7】:

          一个有效的 jQuery 验证示例:

             $(function () {
                  $('input[type=file]').on('change', function() {
                      var $el = $(this);
                      var files = this.files;
                      var image = new Image();
                      image.onload = function() {
                          $el
                              .attr('data-upload-width', this.naturalWidth)
                              .attr('data-upload-height', this.naturalHeight);
                      }
          
                      image.src = URL.createObjectURL(files[0]);
                  });
          
                  jQuery.validator.unobtrusive.adapters.add('imageminwidth', ['imageminwidth'], function (options) {
                      var params = {
                          imageminwidth: options.params.imageminwidth.split(',')
                      };
          
                      options.rules['imageminwidth'] = params;
                      if (options.message) {
                          options.messages['imageminwidth'] = options.message;
                      }
                  });
          
                  jQuery.validator.addMethod("imageminwidth", function (value, element, param) {
                      var $el = $(element);
                      if(!element.files && element.files[0]) return true;
                      return parseInt($el.attr('data-upload-width')) >=  parseInt(param["imageminwidth"][0]);
                  });
          
              } (jQuery));
          

          【讨论】:

            猜你喜欢
            • 2018-08-04
            • 2013-11-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-02-02
            • 1970-01-01
            相关资源
            最近更新 更多