是否可以在上传前检查图像的尺寸?

Is it possible to check dimensions of image before uploading?

提问人:Sabby62 提问时间:11/27/2012 最后编辑:Penny LiuSabby62 更新时间:6/2/2020 访问量:86998

问:

我有一个上传控件,用于将图像上传到服务器,但在上传之前,我只想确保图像的尺寸是否正确。 客户端有什么可以用 JavaScript 完成的吗?

JavaScript jQuery 文件上传 客户端

评论

4赞 adeneo 11/27/2012
在 HTML5 文件 API 中,这是可能的,否则就不可能了!
0赞 Joshua Burns 11/27/2012
这应该可以回答您的问题:stackoverflow.com/questions/5173796/html5-get-image-dimension
0赞 Jaroslav Trsek 11/27/2012
是的,这是可能的。stackoverflow.com/questions/961913/image-resize-before-upload
1赞 11/27/2012
当然(与所有验证一样),尽管在客户端进行检查可能是明智的,但任何客户端都可以伪造它,您仍然应该在服务器端进行验证。

答:

-3赞 webNoob 11/27/2012 #1

试一试。我过去用过这个。https://github.com/valums/file-uploader

评论

4赞 TheCarver 2/21/2015
OP 说他们已经有一个上传控件,但想要一个额外的功能。给他们一个全新的上传控件并不是一个很好的答案。他们想要的只是尺寸。无论如何,该上传者现在已移至此处:github.com/FineUploader/fine-uploader
47赞 Gurpreet Singh 11/27/2012 #2

是的,HTML5 API 支持此功能。

http://www.w3.org/TR/FileAPI/

var _URL = window.URL || window.webkitURL;

$("#file").change(function(e) {

    var image, file;

    if ((file = this.files[0])) {

        image = new Image();

        image.onload = function() {

            alert("The image width is " +this.width + " and image height is " + this.height);
        };

        image.src = _URL.createObjectURL(file);


    }

});​

DEMO(在 chrome 上测试)

评论

2赞 adeneo 11/27/2012
@AlienWebguy - 当然是,请参阅此站点,在删除或选择图像时,名称,文件大小和尺寸会立即更新,而无需将图像上传到服务器。
75赞 Esailija 11/27/2012 #3

您可以在提交表格之前检查它们:

window.URL = window.URL || window.webkitURL;

$("form").submit( function( e ) {
    var form = this;
    e.preventDefault(); //Stop the submit for now
                                //Replace with your selector to find the file input in your form
    var fileInput = $(this).find("input[type=file]")[0],
        file = fileInput.files && fileInput.files[0];

    if( file ) {
        var img = new Image();

        img.src = window.URL.createObjectURL( file );

        img.onload = function() {
            var width = img.naturalWidth,
                height = img.naturalHeight;

            window.URL.revokeObjectURL( img.src );

            if( width == 400 && height == 300 ) {
                form.submit();
            }
            else {
                //fail
            }
        };
    }
    else { //No file was input or browser doesn't support client side reading
        form.submit();
    }

});

这仅适用于现代浏览器,因此您仍然需要检查服务器端的尺寸。你也不能信任 客户端,所以这是您必须在服务器端检查它们的另一个原因。

评论

0赞 HelpNeeder 4/12/2016
不开玩笑,“createObjectURL”直到最近才在 IE 上运行......真是太可惜了。caniuse.com/#search=createObjectURL
1赞 Gabriel Archanjo 4/3/2018 #4

为了简单起见,请使用javascript图像处理框架,如fabric.js,processing.js MarvinJ

MarvinJ 的情况下,只需在客户端加载图像并使用 getWidth() 和 getHeight() 方法来检查图像的尺寸。有了这些维度,您可以允许提交文件或通知用户不兼容的维度。

例:

var image = new MarvinImage();
image.load("https://i.imgur.com/oOZmCas.jpg", imageLoaded);

function imageLoaded(){
  document.getElementById("result").innerHTML += image.getWidth()+","+image.getHeight();
}
<script src="https://www.marvinj.org/releases/marvinj-0.8.js"></script>
<div id="result"></div>

2赞 Klemen Tusar 6/13/2019 #5

可能有点晚了,但这是一个使用承诺的公认答案的现代 ES6 版本

const getUploadedFileDimensions: file => new Promise((resolve, reject) => {
    try {
        let img = new Image()

        img.onload = () => {
            const width  = img.naturalWidth,
                  height = img.naturalHeight

            window.URL.revokeObjectURL(img.src)

            return resolve({width, height})
        }

        img.src = window.URL.createObjectURL(file)
    } catch (exception) {
        return reject(exception)
    }
})

你可以这样称呼它

getUploadedFileDimensions(file).then(({width, height}) => {
    console.log(width, height)
})
1赞 Kaiido 8/7/2019 #6

如果你不需要处理 svg 文件,并且可以将自己限制在最新的浏览器上,那么你可以使用 createImageBitmap 函数来制作一个基于 Promise 的行:

if(typeof createImageBitmap !== "function") {
  console.error("Your browser doesn't support this method");
  // fallback to URL.createObjectURL + <img>
}

inp.oninput = e => {
  createImageBitmap(inp.files[0])
    .then((bmp) => console.log(bmp.width, bmp.height))
    .catch(console.error);
}
<input type="file" id="inp" accept="image/*">

0赞 Adam 6/2/2020 #7

@Klemen Tusar's anser 的扩展,用于多个文件:

const loadImage = file => new Promise((resolve, reject) => {
    try {
        const image = new Image();

        image.onload = function () {
            resolve(this)
        };

        image.onerror = function () {
            reject("Invalid image. Please select an image file.");
        }

        image.src = window.URL.createObjectURL(file);
    } catch (e) {
        reject(e)
    }
})

const loadImagesArray = async files => {
    let images = Array(files.length)
    await Promise.all(files.map((file, i) => (async () => {
        const loadedImage = await loadImage(file)
        images[i] = loadedImage
    })()))
    return images
}

然后,您可以简单地检查加载图像上的内容,如下所示:

const loadedImages = await loadImagesArray(e.currentTarget.files)
for(const loadedImage of loadedImages) {
    console.log(loadedImage.width, loadedImage.height)
}