在使用 Javascript 上传之前检查图像的宽度和高度

我有一个 JPS 表单,用户可以在其中放置一张图片:

<div class="photo">
<div>Photo (max 240x240 and 100 kb):</div>
<input type="file" name="photo" id="photoInput" onchange="checkPhoto(this)"/>
</div>

我写了这样的 js:

function checkPhoto(target) {
if(target.files[0].type.indexOf("image") == -1) {
document.getElementById("photoLabel").innerHTML = "File not supported";
return false;
}
if(target.files[0].size > 102400) {
document.getElementById("photoLabel").innerHTML = "Image too big (max 100kb)";
return false;
}
document.getElementById("photoLabel").innerHTML = "";
return true;
}

它可以很好地检查文件类型和大小。现在我想检查图像的宽度和高度,但我不能这样做。
我试过用 target.files[0].width,但是我得到了 undefined。用其他方法我得到了 0
有什么建议吗?

310379 次浏览

我同意。一旦它被上传到某个地方,用户的浏览器可以访问,然后很容易得到的大小。由于您需要等待图像加载,因此需要为 img挂钩到 onload事件。

最新例子:


// async/promise function for retrieving image dimensions for a URL
function imageSize(url) {
const img = document.createElement("img");


const promise = new Promise((resolve, reject) => {
img.onload = () => {
// Natural size is the actual image size regardless of rendering.
// The 'normal' `width`/`height` are for the **rendered** size.
const width  = img.naturalWidth;
const height = img.naturalHeight;


// Resolve promise with the width and height
resolve({width, height});
};


// Reject promise on error
img.onerror = reject;
});


// Setting the source makes it start downloading and eventually call `onload`
img.src = url;


return promise;
}


// How to use in an async function
(async() => {
const imageUrl = 'http://your.website.com/userUploadedImage.jpg';
const imageDimensions = await imageSize(imageUrl);


console.info(imageDimensions); // {width: 1337, height: 42}
})();


老例子:

var width, height;


var img = document.createElement("img");
img.onload = function() {
// `naturalWidth`/`naturalHeight` aren't supported on <IE9. Fallback to normal width/height
// The natural size is the actual image size regardless of rendering.
// The 'normal' width/height are for the **rendered** size.
    

width  = img.naturalWidth  || img.width;
height = img.naturalHeight || img.height;
    

// Do something with the width and height
}


// Setting the source makes it start downloading and eventually call `onload`
img.src = "http://your.website.com/userUploadedImage.jpg";

这个文件只是一个文件,你需要创建一个像这样的图像:

var _URL = window.URL || window.webkitURL;
$("#file").change(function (e) {
var file, img;
if ((file = this.files[0])) {
img = new Image();
var objectUrl = _URL.createObjectURL(file);
img.onload = function () {
alert(this.width + " " + this.height);
_URL.revokeObjectURL(objectUrl);
};
img.src = objectUrl;
}
});

演示: http://jsfiddle.net/4N6D9/1/

我想你知道这只在少数浏览器中支持。主要是火狐和 Chrome 现在可能也是歌剧了。

URL.createObjectURL()方法已从 MediaStream 接口中移除。这种方法已经在2013年被废弃,并被分配流到 HTMLMediaElement.srcObject所取代。旧方法被删除,因为它不太安全,需要调用 URL.revokeOjbectURL()来结束流。其他用户代理已经否决了(Firefox)或者删除了(Safari)这个特性。

详情请参阅 给你

在我看来,你需要的完美答案是

var reader = new FileReader();


//Read the contents of Image File.
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {


//Initiate the JavaScript Image object.
var image = new Image();


//Set the Base64 string return from FileReader as source.
image.src = e.target.result;


//Validate the File Height and Width.
image.onload = function () {
var height = this.height;
var width = this.width;
if (height > 100 || width > 100) {
alert("Height and Width must not exceed 100px.");
return false;
}
alert("Uploaded image has valid Height and Width.");
return true;
};
};
function uploadfile(ctrl) {
var validate = validateimg(ctrl);


if (validate) {
if (window.FormData !== undefined) {
ShowLoading();
var fileUpload = $(ctrl).get(0);
var files = fileUpload.files;




var fileData = new FormData();




for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}




fileData.append('username', 'Wishes');


$.ajax({
url: 'UploadWishesFiles',
type: "POST",
contentType: false,
processData: false,
data: fileData,
success: function(result) {
var id = $(ctrl).attr('id');
$('#' + id.replace('txt', 'hdn')).val(result);


$('#imgPictureEn').attr('src', '../Data/Wishes/' + result).show();


HideLoading();
},
error: function(err) {
alert(err.statusText);
HideLoading();
}
});
} else {
alert("FormData is not supported.");
}


}
function validateimg(ctrl) {
var fileUpload = $("#txtPostImg")[0];
var regex = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(.jpg|.png|.gif)$");
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (fileUpload.files) != "undefined") {
var reader = new FileReader();
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {
var image = new Image();
image.src = e.target.result;
image.onload = function () {
var height = this.height;
var width = this.width;
console.log(this);
if ((height >= 1024 || height <= 1100) && (width >= 750 || width <= 800)) {
alert("Height and Width must not exceed 1100*800.");
return false;
}
alert("Uploaded image has valid Height and Width.");
return true;
};
}
} else {
alert("This browser does not support HTML5.");
return false;
}
} else {
alert("Please select a valid Image file.");
return false;
}
}

将该函数附加到输入类型 file/Onchange = “ validateimg (this)”/的 onchange 方法

   function validateimg(ctrl) {
var fileUpload = ctrl;
var regex = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(.jpg|.png|.gif)$");
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (fileUpload.files) != "undefined") {
var reader = new FileReader();
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {
var image = new Image();
image.src = e.target.result;
image.onload = function () {
var height = this.height;
var width = this.width;
if (height < 1100 || width < 750) {
alert("At least you can upload a 1100*750 photo size.");
return false;
}else{
alert("Uploaded image has valid Height and Width.");
return true;
}
};
}
} else {
alert("This browser does not support HTML5.");
return false;
}
} else {
alert("Please select a valid Image file.");
return false;
}
}

这是检查尺寸最简单的方法

let img = new Image()
img.src = window.URL.createObjectURL(event.target.files[0])
img.onload = () => {
alert(img.width + " " + img.height);
}

检查特定的尺寸,以100x100为例

let img = new Image()
img.src = window.URL.createObjectURL(event.target.files[0])
img.onload = () => {
if(img.width === 100 && img.height === 100){
alert(`Nice, image is the right size. It can be uploaded`)
// upload logic here
} else {
alert(`Sorry, this image doesn't look like the size we wanted. It's
${img.width} x ${img.height} but we require 100 x 100 size image.`);
}
}

    const ValidateImg = (file) =>{
let img = new Image()
img.src = window.URL.createObjectURL(file)
img.onload = () => {
if(img.width === 100 && img.height ===100){
alert("Correct size");
return true;
}
alert("Incorrect size");
return true;
}
}

你可以做的步骤为 预告片的图像,而不显示它是 支持所有浏览器。下面的 js 代码向您展示了如何检查 widthheight:

var file = e.target.files[0];
if (/\.(jpe?g|png|gif)$/i.test(file.name)) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.src = this.result as string;
image.addEventListener('load', function () {
console.log(`height: ${this.height}, width: ${this.width}`);
});
                

}, false);
            

reader.readAsDataURL(file);
}

基于 Mozilla 文档:

方法用于读取指定的 读取操作完成后,就绪状态 成为 搞定,并且 负载被触发。这时,result 属性包含作为数据的数据: URL 表示文件的 数据作为 基地64编码的字符串。

< strong > 浏览器兼容性 也在名单上。

在我的例子中,我还需要防止表单被提交,所以这里有一个对我有效的解决方案。

PreventDefault 将停止表单操作,然后我们在 onload 函数中检查图像的大小和尺寸。

如果一切正常,我们允许提交。

由于如果用户仍然试图提交带有无效图像的表单,提交按钮将被禁用,我还必须在输入有效图像后重新启用提交按钮。

const validateMaxImageFileSize = (e) => {
e.preventDefault();
const el = $("input[type='file']")[0];


if (el.files && el.files[0]) {
const file = el.files[0];


const maxFileSize = 5242880; // 5 MB
const maxWidth = 1920;
const maxHeight = 1080;


const img = new Image();
img.src = window.URL.createObjectURL(file);
img.onload = () => {
if (file.type.match('image.*') && file.size > maxFileSize) {
alert('The selected image file is too big. Please choose one that is smaller than 5 MB.');
} else if (file.type.match('image.*') && (img.width > maxWidth || img.height > maxHeight)) {
alert(`The selected image is too big. Please choose one with maximum dimensions of ${maxWidth}x${maxHeight}.`);
} else {
e.target.nodeName === 'INPUT'
? (e.target.form.querySelector("input[type='submit']").disabled = false)
: e.target.submit();
}
};
}
};


$('form.validate-image-size').on('submit', validateMaxImageFileSize);
$("form.validate-image-size input[type='file']").on('change', validateMaxImageFileSize);