My goal in using filepond was simply to get uploaded images into some reasonably scaled state via compression and resizing before uploading to an s3 transfer accelerated bucket and transferring to their final destination (when they're queued for additional processing, etc). All is working here for us except that I can't seem to determine where on earth the finished file dimensions are after combing through the documentation.
I am uploading an image using my own "process" function and noticed that the metadata argument has incorrect values for width and height given these settings which leads me to believe metadata is actually just information about my settings that I already know given:
imageResizeTargetWidth=1920
imageResizeUpscale=false
imageResizeMode=contain
We expected to see the resulting width and height in the metadata object. Given an jpeg that measures 5184x3456 here is the metadata object as passed to my process() function as instructed:
process(fieldName, file, metadata, load, error, progress, abort, transfer, options) { ... }
{
"resize": {
"mode": "contain",
"upscale": false,
"size": {
"width": 1920,
"height": 1920
}
},
"color": null,
"output": {
"type": null,
"quality": null,
"client": [
"crop",
"resize",
"filter",
"markup",
"output"
]
}
}
Expected metadata.resize.size.height to equal it's processed which in this case is 1280.
Versions:
{"filepond": "^4.20.1",
"filepond-plugin-file-validate-type": "^1.2.5",
"filepond-plugin-image-preview": "^4.6.4",
"filepond-plugin-image-resize": "^2.0.7",
"filepond-plugin-image-transform": "^3.7.4"}
Adding reference to #122 and #22 both 3 years old.
The metadata object contains resize instructions.
If you need the image size in the process method you can use the getImageSizesnippet from issue #122
Should definitely be accessible somewhere since you already calculated it, though. Not part of Doka payload either.
@rikschennink can you make the uploaded image dimensions accessible in the file object? https://pqina.nl/filepond/docs/patterns/api/file/
The use case here is we want to put the uploaded image onto another <img> element and set it's dimension to the uploaded image.
@tvb Where do you need them? I can look into creating a plugin that adds this info.
You can also run this in the process method:
const img = new Image()
img.onload = () => {
console.log(img.naturalWidth, img.naturalHeight);
URL.revokeObjectURL(img.src);
}
img.src = URL.createObjectURL(file)
@tvb Where do you need them? I can look into creating a plugin that adds this info.
You can also run this in the process method:
const img = new Image() img.onload = () => { console.log(img.naturalWidth, img.naturalHeight); URL.revokeObjectURL(img.src); } img.src = URL.createObjectURL(file)
What I am now doing is once the file has been added to the pond (but not uploaded/saved) I want the image to be displayed elsewhere on the page as a preview. This is what I am doing now to achieve this. Which works, I guess..
$.fn.filepond.setOptions({
onaddfile: function (error, file) {
if (error === null) {
var imgtag = document.getElementById("page_logo");
imgtag.title = "logo." + file.fileExtension;
var reader = new FileReader();
reader.readAsDataURL(file.file);
reader.onload = function (event) {
imgtag.src = event.target.result;
var image = new Image();
image.src = event.target.result;
image.onload = function () {
$('#page_logo').width(this.width);
$('#page_logo').height(this.height);
};
};
}
},
});
The dimensions should be known already, right? If so, the var image = new Image() would not be needed and the original dimensions of the uploaded file can be fetched from the image metadata (before any resize happend).
For example:
$('#page_logo').width(file.naturalWidth);
$('#page_logo').height(file.naturalHeight);
Let me know what you think @rikschennink 馃憤馃徎
@tvb I think this is (at this moment) the best approach. FilePond is not purely aimed at handling image files so that's the reason why it's not available by default.
This is the function I use in the next version of Doka, it quickly gets the correct image size without waiting for the entire image to load.
const getImageSize = (imageElement: HTMLImageElement) =>
new Promise<Size>((resolve, reject) => {
let shouldAutoRemove = false;
// test if image is attached to DOM, if not attached, attach so measurement is correct on Safari
if (!imageElement.parentNode) {
shouldAutoRemove = true;
imageElement.style.cssText = `position:absolute; visibility:hidden; pointer-events:none`;
document.body.appendChild(imageElement);
}
// start testing size
const measure = () => {
const width = imageElement.naturalWidth;
const height = imageElement.naturalHeight;
const hasSize = width && height;
if (!hasSize) return;
// clean up image if was attached for measuring
if (shouldAutoRemove) imageElement.parentNode.removeChild(imageElement);
clearInterval(intervalId);
resolve({ width, height });
};
imageElement.onerror = (err) => {
clearInterval(intervalId);
reject(err);
};
const intervalId = setInterval(measure, 1);
measure();
});
You can use it like this
getImageSize(imageElement).then(size => {
console.log(size);
})
// or
const size = await getImageSize(imageElement);
console.log(size);
Gotcha! Thanks, I like Doka and will probably get a license at some point in time, but until then I will stick with my current code. Or change it if you decide to make a plugin for it!
Most helpful comment
Gotcha! Thanks, I like Doka and will probably get a license at some point in time, but until then I will stick with my current code. Or change it if you decide to make a plugin for it!