It would be useful to be able to perform file size reduction of images prior to upload. If a callback could be defined which is called at the very beginning of image dialog, the fileList/blob could be modified by this callback function and returned to the image dialog plugin for further processing and upload. How the callback could look like I can post an example here if/when this is implemented.
Hi, @MRB60
You can use the onImageUploadBefore event.
Ok thanks - not sure how to do that since I need to modify blob contents/resolution size and this function does not return new contents - changing function arguments I presume is not the way. I also believe is is called too late in the process for that looking at the image plugin code.
However, although it would be the preferred way since image upload size would then not be a limit anymore (file size reduced by browser before upload), I now handle it on the server side for the time being. This issue can be closed.
Currently, it seems difficult to adjust the file size before uploading.
How about letting onImageUploadBefore return a new file list?
Yes, it may work. File size checks are done prior to call and info prepared but not sure if this is a problem if the actual file blob (and w/h) is changed. I can make a try if onImageUploadBefore can return a new file list.
Ok, I will modify the code as below: image.js#L395
if (typeof this.functions.onImageUploadBefore === 'function') {
files = this.functions.onImageUploadBefore(files, info, this);
if (!files) return;
}
Code might become backward incompatible in case someone today returns true (would destroy files variable) so better make a warning in changelog. Or make an additional test on true before assigning "files".
The 2.30.0 version has been updated.
If this issue has not been resolved, please reopen this issue.
Thank you.
Currently it runs async.
Is resizing possible?
You are correct.
Blob generation needed for image resize runs async (e.g. "callback" needed) so it is not possible. I have an implemention in js but cannot use it with Suneditor today due to this async needs. I realized this late when looking into Suneditor src.
Promise is not supported in IE.
Did you have any idea?
In my solution, I will not support IE but blob generation is supported in IE (with own vendor prefix).
Blob generation is asynchronous and only requires a callback:
[]https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob
I do not think promise is mandatory.
@MRB60 @hongku
How about this format?
const callBack = function (handler) {
const newFiles;
handler(newFiles);
}
editor.uploadBefore = function (files, info, core, uploadHandler) {
callBack(uploadHandler);
return "await"
}
What does uploadhandler return?
"uploadhandler" is upload method of plugin. plugins.image.upload.bind(core, info)
A function that executed when "uploadBefore" returns true.
I did not use async/await to implement canvas to blob. I used a simple callback and thus I do not completely follow your suggestion on how to continue execution and make the upload of the new files.
See: []https://javascript.info/blob, there both callback method and async/await method is described.
Update:
if uploadHandler is the core function which takes care of the upload to server, I assume it should work. In the callback(), the blob creation(s) can be started and when completed, the uploadHandler is called with a new file list.
If undefined is returned from "uploadBefore", it waits until "uploadHandler" is executed.
"uploadHandler" is an upload function with "core" and "info" bound.
editor.uploadBefore = function (files, info, core, uploadHandler) {
setTimeout(function() {
// upload files
uploadHandler(files /* or [new File(...)] */);
// error
uploadHandler('Error message');
// Just finish with don't upload
uploadHandler();
},1000)
}
Example:
function ResizeImage (files, uploadHandler) {
const uploadFile = files[0];
const img = document.createElement('img');
const canvas = document.createElement('canvas');
const reader = new FileReader();
reader.onload = function (e) {
img.src = e.target.result
img.onload = function () {
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
const MAX_WIDTH = 200;
const MAX_HEIGHT = 100;
let width = img.width;
let height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(function (blob) {
uploadHandler([new File([blob], uploadFile.name)])
}, uploadFile.type, 1);
}
}
reader.readAsDataURL(uploadFile);
}
editor.onImageUploadBefore = function (files, info, core, uploadHandler) {
console.log('files--', files);
console.log('info--', info);
ResizeImage(files, uploadHandler)
// return undefined
}
The 2.30.1 version has been updated.
If this issue has not been resolved, please reopen this issue.
Thank you.
Tried your example but am getting uploadHandler not a function error
my working example:
after create:
suneditor.onImageUploadBefore = function (files, info, core, uploadHandler) {
ResizeImage(files, uploadHandler)
}
and ResizeImage:
function ResizeImage (files, uploadHandler) {
const uploadFile = files[0];
const img = document.createElement('img');
const canvas = document.createElement('canvas');
const reader = new FileReader();
reader.onload = function (e) {
img.src = e.target.result
img.onload = function () {
let ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
const MAX_WIDTH = IMMAXWIDTH;
const MAX_HEIGHT = IMMAXHEIGHT;
let width = img.width;
let height = img.height;
if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
canvas.toBlob(function (blob) {
uploadHandler([new File([blob], uploadFile.name)])
}, uploadFile.type);
}
}
reader.readAsDataURL(uploadFile);
}
Worked with Suneditor v2.31.0
ok, thanks
One more thing. How do I implement this in react, the uploadHandler is not recognised as a function.
Most helpful comment
Example: