DEV Community

Cover image for Let's write an image converter in 20 lines of html+js
Nino Filiu
Nino Filiu

Posted on

Let's write an image converter in 20 lines of html+js

For those who just wanna see the code, it's on my codepen

Out of all the things you can do with web APIs, my fav arena has got to be playing around with the canvas. It basically offers you a rectangle you can draw anything you like - whether it's a bunch of colorful circles or a more exotic objects like a video frame; along with utilities to read out the RGB values of the whole stuff.

One of its powerful features is toDataURL that can export the current canvas image into the format of your choice, like image/jpeg or image/png, and we're gonna use it to write our converter.

Let's start off with some basic inputs to ask the user for an image and to specify the desired output format and compression rate. The <img> will be where we'll display our converted and compressed image:

File: <input type="file" accept="image/*"><br>
Convert to: <input value="image/jpeg"><br>
Quality: <input type="number" min="0" max="1" step="0.01" value="0.9"><br>
<button>Convert</button><br>
<img>
Enter fullscreen mode Exit fullscreen mode

Then the JS to get a handle on these element:

const [fileInput, typeInput, qualityInput] = document.querySelectorAll('input');
const outImg = document.querySelector('img')
document.querySelector('button').addEventListener('click', async () => {
  // TODO
});
Enter fullscreen mode Exit fullscreen mode

We can get a hold of the image uploaded by the user by looking up fileInput.files which contains a list of Files from which you can make a URL with URL.createObjectURL

const [file] = fileInput.files;
if (!file) return alert('file required');
const srcImg = document.createElement('img');
srcImg.src = URL.createObjectURL(file);
Enter fullscreen mode Exit fullscreen mode

Now we have an Image of whatever the user uploaded, but before we draw it on a canvas, we have to wait for it to load using .decode. Note that we adjust the canvas dimensions to the image dimensions, else the picture is going to be cropped:

await srcImg.decode();
const canvas = document.createElement('canvas');
canvas.width = srcImg.width;
canvas.height = srcImg.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(srcImg, 0, 0);
Enter fullscreen mode Exit fullscreen mode

Now time to use this tiny function that actually exposes a lot of browser "intelligence" in terms of image formats:

outImg.src = canvas.toDataURL(typeInput.value, +qualityInput.value);
Enter fullscreen mode Exit fullscreen mode

And... voilà!

You now have a minimal image converter + compressor.

Hope you've learned something interesting about image web APIs today!

Top comments (0)