How to Check Image Dimensions (Width and Height) Before Upload in JavaScript
Validating image dimensions on the client-side, before a file is uploaded, is a crucial feature for a good user experience. It allows you to provide immediate feedback to the user (e.g., "Image is too small") and can save server resources and bandwidth by preventing invalid uploads.
This guide will teach you the modern, standard method for reading an image's dimensions from a file input. You will learn how to create a reusable, Promise-based function to handle the asynchronous nature of file reading and then apply it to both single and multiple file inputs.
The Core Challenge: Reading Image Dimensions is Asynchronous
You cannot get an image's dimensions synchronously. When a user selects a file, the browser needs time to load and process it to determine its properties like width and height. Any attempt to access these properties immediately will fail. The solution is to use an event-driven, asynchronous approach to wait for the image to load.
The Modern Solution: A Reusable async Function
The best practice is to encapsulate the file-reading logic into a reusable function that returns a Promise. This makes your main code much cleaner and easier to read.
The logic:
- Create a function that accepts a
Fileobject. - Inside, create a
Promise. - Use
URL.createObjectURL()to create a temporary, in-memory URL for the selected file. - Create a new
Imageelement and set itssrcto this URL. - Listen for the
onloadevent. When it fires, the image has been processed, and itswidthandheightproperties are available. Resolve thePromisewith these dimensions. - Listen for the
onerrorevent to handle cases where the file is not a valid image. - Crucially, call
URL.revokeObjectURL()after you're done to free up browser memory.
Example of a Reusable Function:
/**
* Gets the dimensions of an image file.
* @param {File} file The image file.
* @returns {Promise<{width: number, height: number}>} A promise that resolves with the image dimensions.
*/
function getImageDimensions(file) {
return new Promise((resolve, reject) => {
const img = new Image();
const objectURL = URL.createObjectURL(file);
img.onload = () => {
// The image has been loaded, its dimensions are now available.
resolve({ width: img.width, height: img.height });
// Clean up the object URL to free memory.
URL.revokeObjectURL(objectURL);
};
img.onerror = () => {
reject(new Error('Could not load image file.'));
URL.revokeObjectURL(objectURL);
};
// This triggers the image loading.
img.src = objectURL;
});
}
Practical Examples
With our getImageDimensions utility function, checking files from an input becomes incredibly clean.
How to Check a Single Image File
This example shows how to validate a single selected image.
<input id="file-input" type="file" accept="image/*" />
<p id="feedback"></p>
const fileInput = document.getElementById('file-input');
const feedback = document.getElementById('feedback');
fileInput.addEventListener('change', async (event) => {
const file = event.target.files[0];
if (!file) {
return; // No file selected
}
try {
const { width, height } = await getImageDimensions(file);
feedback.textContent = `Selected image dimensions: ${width}x${height}`;
if (width < 100 || height < 100) {
feedback.textContent += ' (Error: Image must be at least 100x100px).';
} else {
feedback.textContent += ' (Success: Image meets size requirements).';
}
} catch (error) {
feedback.textContent = `Error: ${error.message}`;
}
});
How to Check Multiple Image Files
The same reusable function works perfectly when a user selects multiple files. We just need to loop through the FileList object.
<input id="multi-file-input" type="file" accept="image/*" multiple />
<ul id="multi-feedback"></ul>
const multiFileInput = document.getElementById('multi-file-input');
const multiFeedback = document.getElementById('multi-feedback');
multiFileInput.addEventListener('change', (event) => {
const files = event.target.files;
multiFeedback.innerHTML = ''; // Clear previous results
if (!files.length) {
return;
}
for (const file of files) {
getImageDimensions(file)
.then(({ width, height }) => {
const listItem = document.createElement('li');
listItem.textContent = `File: ${file.name}, Dimensions: ${width}x${height}.`;
if (width < 100 || height < 100) {
listItem.textContent += ' (Error: Too small)';
listItem.style.color = 'red';
}
multiFeedback.appendChild(listItem);
})
.catch(error => {
const listItem = document.createElement('li');
listItem.textContent = `File: ${file.name} - ${error.message}`;
listItem.style.color = 'red';
multiFeedback.appendChild(listItem);
});
}
});
Conclusion
Client-side validation of image dimensions is a crucial feature for modern web applications.
- The process is inherently asynchronous, as the browser must load the file to read its metadata.
- The best practice is to create a reusable,
Promise-based function that encapsulates the logic ofURL.createObjectURL, theImageobject, and itsonloadevent. - Always remember to call
URL.revokeObjectURL()to prevent memory leaks in the browser.
By using this modern, modular approach, you can write clean, readable, and efficient code to validate image dimensions before they are ever sent to your server.