-
Notifications
You must be signed in to change notification settings - Fork 439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compress more than one image #46
Comments
const imageCompressor = new ImageCompressor();
Promise.all([
imageCompressor.compress(file1),
imageCompressor.compress(file2),
imageCompressor.compress(file3),
]).then(([result1, result2, result3) => {
// Handle the compressed image files.
}).catch((err) => {
// Handle the error
}); |
can you please provide an example with a new(?) way (passing file into the constructor) and a for loop? I have a "multiple" file input and need to compress all of the output files before sending them to the server. |
I still don't understand the author's comment, so I'll answer myself and anyone else who stumbles upon this. First, you need to create a function that compresses an image and returns a promise: compressImage(file: File): Promise<File> {
return new Promise<File>((resolve, reject) => {
new Compressor(file, {
...someOptions,
success: (result) => {
resolve(new File([result], file.name, {type: result.type}))
},
error: (error: Error) => reject(error)
})
});
} so you can use it like this: public async onFileInputChange(files: File[]) {
// collect promises from the compression function
const compressPromises: Promise<File>[] = [];
for (const file of files) {
compressPromises.push(this.compressImage(file));
}
// wait until these properties are resolved and loop through the result
Promise.all(compressPromises).then((compressedFiles) => {
for (const file of compressedFiles) {
// do whatever you need to do with these files - upload to server or whatever
}
})
.catch((error) => console.log('ooops :(', error))
} |
Coming from Python, I wrote this function which at least makes it understandable (for me) what is happening: // returns a promise so the function can be used with await compressImages()
function compressImages(){
return new Promise(async function(resolve){
let processedImages = 0
let numImagesToProcess = $images.files.length
for (let i = 0; i < numImagesToProcess; i++){
const file = $images.files[i]
await new Promise(resolve =>{
new Compressor(file, {
quality: 0.5,
success(result){
$images.files[i] = result
resolve()
}
})
})
processedImages += 1
}
if (processedImages === numImagesToProcess){
resolve()
}
})
} |
@grreeenn Just wanted to say thank you for this suggestion. I've been looking for away to free my compressed files that compressorjs has been holding hostage so that I can use async await as well as write tests by mocking out the helper function and get around compressorjs in tests. This solution was immensely helpful. Thank you! |
I made an example. Would you mind terribly helping me to learn how to use your method? I have it setup for compressor.js here: https://codepen.io/warrenkc/pen/XWMYGxE?editors=0011 |
Sure! The function is pretty ugly and I used some global variables. I guess the latter is the predominant reason why it's not working for you. This should work (sorry I don't have a Codepen account): btnResize.addEventListener("click", async function () {
let compressedImages = [];
// the function uses the file input dom element directly.
// compressedImages is an empty array which will contain
// the compressed images after processing.
await compressImages(fileInput, compressedImages);
console.log(compressedImages.length);
}); async function compressImages(fileInput, output){
return new Promise(async function(resolve){
let numProcessedImages = 0
let numImagesToProcess = fileInput.files.length
for (let i = 0; i < numImagesToProcess; i++){
const file = fileInput.files[i]
await new Promise(resolve =>{
new Compressor(file, {
quality: 0.5,
success(result){
output.push(result)
resolve()
}
})
})
numProcessedImages += 1
}
if (numProcessedImages === numImagesToProcess){
resolve()
}
})
} |
Thank you. I am trying to figure out a way to process the files before uploading them to the server. |
Example for compressing multiple image files one by one: async function compress(files) {
for (const file of files) {
await new Promise((resolve, reject) => {
new Compressor(file, {
success: resolve,
error: reject,
});
});
}
}
compress(files).then((result) => {
console.log('Compress success');
}).catch((err) => {
console.log('Compress error');
}).finally(() => {
console.log('Compress complete');
}); |
Thank you. Here is the updated example: https://codepen.io/warrenkc/pen/ZEeqxOz?editors=0011 |
@warrenkc Yes, it works fine. |
Thank you so much. I want to show you a video of what happens in Safari on the 4th gen iPad. |
I have not idea on this, maybe you can defer calling the // resolve();
setTimeout(() => {
resolve();
}, 1000); |
Hello,
is there a way to compress in one set more than one image?
The text was updated successfully, but these errors were encountered: