Configure the picker options
Users can accept or reject selected files by using a special feature of the onFileSelected
callback option to the picker. If the function throws an error, the file is rejected, and an error message is displayed. However, you can also return a Promise, and if the Promise is rejected, the file is also rejected with a notification.
This support for Promises makes asynchronous validation possible, which means we can check image dimensions for local files.
In order to make this happen, we need to make sure the option exposeOriginalFile
is true
. This will ensure we can work with the actual File object that represents the user’s file on disk.
function checkImgSize (file) {
return new Promise(function (resolve, reject) {
const maxWidth = 1300;
const maxHeight = 1300;
const blob = file.originalFile;
// Get an object URL for the local file
const url = URL.createObjectURL(blob);
// Create an image and load the object URL
const img = new Image();
img.src = url;
img.onload = function () {
URL.revokeObjectURL(url);
if (this.naturalWidth > maxWidth) {
reject('File is too wide');
}
if (this.naturalHeight > maxHeight) {
reject('File is too tall');
}
// If we made it here then the file was approved
resolve();
}
});
}
const picker = client.picker({
exposeOriginalFile: true,
onFileSelected: checkImgSize,
});
Using this simple function, you ensure that local images are the right size before they are selected. In combination with maxSize
and the image resizing options (imageMin
, imageMax
, imageDim
), the picker provides a helpful set of features to ensure that your image requirements are met.
As a side note, loading the entire image into memory may not be optimal for your use case. It is also possible to read just a slice of the file to retrieve its EXIF data, if present, and use that to determine image dimensions. This can be accomplished inside of a web worker to avoid performance issues, and we will explore this in another tutorial.