【问题标题】:Getting Image Dimensions using Javascript File API使用 Javascript 文件 API 获取图像尺寸
【发布时间】:2011-11-19 14:09:55
【问题描述】:

我需要在我的 Web 应用程序中生成图像的缩略图。我使用 Html 5 File API 来生成缩略图。

我利用以下 URL 中的示例生成缩略图。

http://www.html5rocks.com/en/tutorials/file/dndfiles/

我能够成功生成缩略图。我遇到的问题是我只能通过使用静态大小来生成缩略图。有没有办法从所选文件中获取文件尺寸,然后创建 Image 对象?

【问题讨论】:

标签: javascript thumbnails fileapi


【解决方案1】:

是的,将文件作为数据 URL 读取并将该数据 URL 传递给 Imagesrchttp://jsfiddle.net/pimvdb/eD2Ez/2/

var fr = new FileReader;

fr.onload = function() { // file is loaded
    var img = new Image;

    img.onload = function() {
        alert(img.width); // image is loaded; sizes are available
    };

    img.src = fr.result; // is the data URL because called with readAsDataURL
};

fr.readAsDataURL(this.files[0]); // I'm using a <input type="file"> for demonstrating

【讨论】:

  • img.onload = function() { 从不触发
  • img.onload之前做img.src = fr.result;
  • img.onloadonloadImage 事件的处理程序,并且只会在加载某些内容后调用。在这种情况下,img.src = fr.result; 将触发 onload 事件。从语义上讲,您希望在您的事件可能触发之前绑定您的事件处理程序。如果onload 没有触发,请尝试img.onerror = function(err) { console.error(err); } 以查看文件读取器是否未能加载Image 可以处理的内容。 (或者如果出现其他问题)
【解决方案2】:

或使用对象 URL:http://jsfiddle.net/8C4UB/

var url = URL.createObjectURL(this.files[0]);
var img = new Image;

img.onload = function() {
    alert(img.width);
    URL.revokeObjectURL(img.src);
};

img.src = url;

【讨论】:

  • 这种方法不会将图像加载到内存中。 readAsDataURL 可以。 stackoverflow.com/questions/6217652/…
  • 一般情况下最好撤销onload处理程序中的url:URL.revokeObjectURL(url)
【解决方案3】:

现有的答案对我帮助很大。但是,img.onload 事件导致的奇怪事件顺序让我觉得有些混乱。所以我调整了现有的解决方案,并将它们与基于承诺的方法相结合。也许这对其他人有帮助。

这是一个函数,它返回一个以对象为维度的承诺:

const getHeightAndWidthFromDataUrl = dataURL => new Promise(resolve => {
  const img = new Image()
  img.onload = () => {
    resolve({
      height: img.height,
      width: img.width
    })
  }
  img.src = dataURL
})

下面是你如何将它与异步函数一起使用:

// Get a file from an input field
const file = document.querySelector('[type="file"]').files[0]

// Get the data URL of the image as a string
const fileAsDataURL = window.URL.createObjectURL(file)

// Get dimensions 
const someFunction = async () => {
  const dimensions = await getHeightAndWidthFromDataUrl(fileAsDataURL)
  // Do something with dimensions ...
}

下面是使用 then() 语法的方法:

// Get a file from an input field
const file = document.querySelector('[type="file"]').files[0]

// Get the data URL of the image as a string
const fileAsDataURL = window.URL.createObjectURL(file)

// Get the dimensions
getHeightAndWidthFromDataUrl(fileAsDataURL).then(dimensions => {
  // Do something with dimensions
})

【讨论】:

  • 我在互联网上找到的唯一相关答案。非常感谢先生ヽ( ̄д ̄)ノ
【解决方案4】:

我在我的项目中将 pimvdb 答案包装在一个通用函数中:

function checkImageSize(image, minW, minH, maxW, maxH, cbOK, cbKO){
    //check whether browser fully supports all File API
    if (window.File && window.FileReader && window.FileList && window.Blob) {
        var fr = new FileReader;
        fr.onload = function() { // file is loaded
            var img = new Image;
            img.onload = function() { // image is loaded; sizes are available
                if(img.width < minW || img.height < minH || img.width > maxW || img.height > maxH){  
                    cbKO();
                }else{
                    cbOK();
                }
            };
            img.src = fr.result; // is the data URL because called with readAsDataURL
        };
        fr.readAsDataURL(image.files[0]);
    }else{
        alert("Please upgrade your browser, because your current browser lacks some new features we need!");
    }
}    

【讨论】:

    猜你喜欢
    • 2011-08-03
    • 2011-02-21
    • 2015-03-27
    • 2018-07-31
    • 2012-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多