Client side image resizing before upload?

Hi~ Can someone tell me how to import the javascript compressor and how to use it? I tried adding the javascript to import the compressor in my workflow and it doesn’t work.

Hi @Kkluz :wave:

Can you clarify what image resizing library you are trying to use?

Basically I want to allow my users to upload image files. However, any image size that are over 500kb will be compressed to 500kb.
I’ve read this thread in community:
Client side image resizing before upload? Alternative to using TinyPNG after upload - #2 by luka

and one member suggested using :compressorjs CDN by jsDelivr - A CDN for npm and GitHub

I opened the link but I have no idea how to “install” the script in weweb.

Got it!

I recorded this video to walk you through the process.

To summarize, there are a couple of things you’ll need to do.

First, add the npm plugin, search for compressorjs and add that library to your project:

Second, in your workflow, before you upload the file, you will need to add a Custom Javascript action that will look something like this:

async function compressFile() {
  let originalFile = variables[/* Input File Drop - value */ 'c9397c14-a7ac-4d49-b8df-9e0e88167aaa-value']?.[0];

  while (!originalFile) {
    // Wait until originalFile is not null
    await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second
    originalFile = variables[/* Input File Drop - value */ 'c9397c14-a7ac-4d49-b8df-9e0e88167aaa-value']?.[0];
  }

  const regex = /^.*base64/;

  return new Promise((resolve, reject) => {
    new Compressor(originalFile, {
      quality: 0.9,
      maxWidth: 300,
      maxHeight: 300,
      checkOrientation: false,
      success: (result) => {
        console.log("Compression successful");
        resolve(result); // This will return the compressed file
      },
      error: reject,
    });
  })
  .catch((error) => {
    console.log("Compress error");
    window.alert(error.message);
  })
  .finally(() => {
    console.log("Compress complete");
  });
}

return compressFile();

The above code snippet is just a starting point:

  • make sure to update the originalFile variable
  • if you’re working with the multiple file upload element, make sure to reference a single object (i.e. a single file) and not an array of objects
  • feel free to edit the code and adjust how the file will be compressed. here’s the library’s documentation to help you adjust the code snippet based on your needs

Hope it helps!

1 Like

Thanks alot!!! I will give it a try~~ Hope it works~~ thank you

1 Like

I am running into an error in workflow where it cannot find the file.

This is the workflow I am currently using:

The workflow keeps showing error at the part when I need to encode the compressed image.
“File not found”
However, it works when I manually click the test button in the workflow.

This is the javascript that I am using: I’ve set the “originalFile” to the result from Fetch_large_image:

async function compressFile() {
let originalFile =context.workflow[‘4fa008ad-5fc7-4bab-8830-a58defa24c55’].result;

while (!originalFile) {
// Wait until originalFile is not null
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second
originalFile =context.workflow[‘4fa008ad-5fc7-4bab-8830-a58defa24c55’].result;
}

const regex = /^.*base64/;

return new Promise((resolve, reject) => {
new Compressor(originalFile, {
quality: 0.9,
maxWidth: 300,
maxHeight: 300,
checkOrientation: false,
success: (result) => {
console.log(“Compression successful”);
resolve(result); // This will return the compressed file
},
error: reject,
});
})
.catch((error) => {
console.log(“Compress error”);
window.alert(error.message);
})
.finally(() => {
console.log(“Compress complete”);
});
}

return compressFile();

Please let me know how I can solve this problem. Thanks for reading this.

You can also consider uploadcare.

It works when I manually click “compress image” in my workflow but it runs into error saying “failed to find file” when I upload my image.

Hi @Kkluz :wave:

Mmm I’m not sure what might be going wrong.

Would you mind recording a short video showing us the bindings in your workflow, the logs when you test the workflow and when you test in preview mode?

Ok I recorded a short video.

When I upload the image, the workflow will run into an error stating “File not found”. However, when I click on test within the workflow, the compress process can be done without any problem.

Hi @Joyce and team!

Thank you very much for the excellent manual. We are also interested in the idea of ​​implementing file compression into SNDQ projects. Unfortunately, we also face the same problems as other developers.

We receive the alert “The first argument must be a File or Blob object.”
In test mode we get an error from the server “Value is not properly formed.”, file object expected. The same api works well with not-compressed file value.

Here is a short video to describe our difficulties:

I have the same issue with trying to test in the editor. When I asked weeks ago, was told it was an async issue, but there wasn’t any guidance on how to fix. But the workflow does work in my published app. I have hundreds of images uploaded every day by my users.

I use the Input File Drop component. I allow multiple images to be selected which is why I loop through them. The output result of the custom JS goes to the Encode File As Base64 component with the Data URL format selected. The result of that gets saved in an array variable. Once the images are compressed and converted, they are displayed to the user, that then clicks an upload button that takes the array variable and send it to Xano in a workflow.

Here is my workflow:

Here is the JS compressing code:

async function compressFile() {
  let originalFile = context.workflow['0ff13d37-2fda-41c8-a6b6-505ca2b2120e'].loop?.['item'];

  while (!originalFile) {
    // Wait until originalFile is not null
    await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for 1 second
    originalFile = context.workflow['0ff13d37-2fda-41c8-a6b6-505ca2b2120e'].loop?.['item'];
  }

  const regex = /^.*base64/;

  return new Promise((resolve, reject) => {
    new Compressor(originalFile, {
      quality: 0.92,
      maxWidth: 600,
      maxHeight: 800,
      checkOrientation: false,
      success: (result) => {
        console.log("Compression successful");
        resolve(result); // This will return the compressed file
      },
      error: reject,
    });
  })
  .catch((error) => {
    console.log("Compress error");
    window.alert(error.message);
  })
  .finally(() => {
    console.log("Compress complete");
  });
}

return compressFile();```

Hi @maryna :wave:

In your video, you are binding to an array, not an object.

The file needs to be an object. If you look at the video and code snippet I shared above, you’ll see I bound to the file object inside the file upload variable (see this passage in the video). The reason I had to do that is that I am using the file upload element in “Multiple” mode and, as a result, the variable is an array of objects.

Does that help?

Hi @ericp :wave:

Your workflow and code snippet look good to me but I’m not proficient in JS, wouldn’t know how to fix that in the editor off the top of my head. If you’d like to share a link to your project in a private message, I can take a look.

Sorry to bother you Joyce~ Is there a way to fix my “File not found” error?~ Just a little worried that you might’ve missed my video above~

Hi @Kkluz :wave:

Ah no, I didn’t miss it but forgot to click on “Reply” with my answer :sweat_smile:

Looking at your video, everything looked ok to me but I did have a little bit of trouble following along because it looked like two things were highlighted in red: the first true/false condition and the encode file action. As a result, I wasn’t sure what was happening.

Could you try recording a video with the following flow:

  • in preview mode, upload a file,
  • in editing mode, open the workflow and clear the logs,
  • then test the workflow so we can see clearly where it fails and go step by step to show each action and binding and error message so we can try to figure out what may be going wrong

Weweb says I’ve replied you three times and shoul send you private message instead.
Below is the video I took~

Basically when I upload an image it says “File not found” and when I enter edit mode and test it, everything works.

Another thing to note is, this workflow used to work when I first made it. It just doesn’t work the next day all of a sudden.

Ah ok, got it! I see what you mean now. Thanks for taking the time to record a second video :slight_smile:

Unfortunately, I don’t know why it’s not working in preview mode but works fine when you test the workflow :confused:

Could you create a support ticket here so the tech team can look into it further in the context of your app? If possible, it would also be great if you let us know in the ticket if the workflow works as expected on the published app.

Ok~ if that is the case, I shall publish it and test it before sending a ticket.
Thanks a lot for your time and effort Joyce~

I have the same bug. Have you managed to fix this issue @Kkluz ?