[Vuejs]-Nuxt convert image to webp before sending to AWS S3

1👍

Eventually, I was able to solve my problem without using any package, and what I did was simply convert the image to a canvas and then I converted the image to WEBP format. Below is my solution.

    convertImage(file) {
        return new Promise((resolve) => {
            // convert image
            let src = URL.createObjectURL(file)
            let canvas = document.createElement('canvas');
            let ctx = canvas.getContext('2d')

            let userImage = new Image();
            userImage.src = src

            userImage.onload = function() {
                canvas.width = userImage.width;
                canvas.height = userImage.height;
                ctx.drawImage(userImage, 0, 0);

                let webpImage = canvas.toDataURL("image/webp");
                return resolve(webpImage);
            }
        });    
    },

so, the function above first receives a file which is the image you want to convert from file input, then it converts the image into a canvas then converts the canvas back into an image, but this time you specify the format of the image you want to convert it into.

Since in my case, I wanted a webp image, I set canvas.toDataURL("image/webp") and by default, the quality of the WEBP image will be the same quality as the image that is received. if you want to reduce the quality to lower quality, the canvas.toDataURL("image/webp", 1) takes another argument which is a number between 0-1, 1 for the highest quality, and 0 lowest quality. you could set 0.5 for medium quality too, or whatever you want. You could also set other file formats you want through the first argument like canvas.toDataURL('image/jpeg', 1.0)— for jpeg format or canvas.toDataURL('image/png', 1.0)–for png.

sources

the small channel where I found my solution – Where I found my solution

developer.mozilla.org explanation – more on the CanvasElement.toDataURL()

2👍

you could use the packages imagemin and imagemin-webp as answered here: Convert Images to webp with Node

2👍

As I’ve explained you in your previous question, you cannot use a Node.js plugin into a client side app, especially when this one is already running and especially if you’re hosting it as target: static on some Vercel or alike platform.

On top of this, image processing is pretty heavy in terms of required processing. So, having an external server that is doing this as a middleware is the best idea. You’ll be able to make a load balancer, allocate auto-scaling, prevent a client side timeout and allow for a simpler way to debug things (maybe even more benefits actually).
You could maybe even do it on a serverless function, if you will not be bothered to much with slower cold starts.

TLDR:

  • simple and efficient solution, put a Node.js server in-between your Nuxt and your S3 bucket
  • more affordable one but more complex, call a serverless function for this (not even sure that this will be performant)
  • wait for Nuxt3 with Nitro, and make some shenigans with a local serviceWorker and Cloudflare workers, in edge-rendering (not even sure that this is the most adapted way of handling your issue neither)
  • maybe try to see for a not so expensive online service to handle the middleware for you

At the end, Image or Video is heavy and expensive to process. And doing those things require quite some knowledge too!

👤kissu

Leave a comment