Image Compression using JavaScript in Retool
- General
Image Compression using JavaScript in Retool
Large image takes more space and time to load and thus needs to be compressed . The biggest trade-off in image compressing is depletion of image quality so a perfect compression is where image quality is acceptable and as well as its size is also considerably reduced . Compression can be of two type lossy and lossless , in lossless the image size is not compressed much but image quality is well preserved , counter to this in lossy compression the image size is compressed significantly but image quality is depleted and this loss is irreversible one can not get original image back from the resultant image . Earlier JPEG (Joint Photographic Experts Group) was used for lossy image compression but nowadays JPEG-2000 is used which provides support for both lossy and lossless compression .
Now let’s see how we can compress image using JavaScript in Retool :
This will be a lossy compression , and we will be using Canvas to achieve the desired output .
Aim : To compress image before uploading it to any cloud server .
-> Once image is uploaded on Retool we are fetching its details and processing it .
1 2 3 4 |
let dataUrl = 'data:'+fileInput1.files['0'].type+';base64,'+fileInput1.value[0]; let imageType = fileInput1.files['0'].type let resolution = 400 // max width/height in pixels let quality = .8 //quality can be between 0.00 to 1.00 here 0.8 means 80% of current quality |
->After loading the image in JavaScript we can compress its size in 2 ways , 1 either by reducing its size (height and width) or reducing pixels density
For reducing its height and width :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
async function downscaleImage( dataUrl, imageType, // e.g. 'image/jpeg' resolution, // max width/height in pixels quality // e.g. 0.9 = 90% quality ) { // Create a temporary image so that we can compute the height of the image. const image = await getImage(dataUrl); const oldWidth = image.naturalWidth; const oldHeight = image.naturalHeight; console.log('dims', oldWidth, oldHeight); const longestDimension = oldWidth > oldHeight ? 'width' : 'height'; const currentRes = longestDimension == 'width' ? oldWidth : oldHeight; console.log('longest dim', longestDimension, currentRes); if (currentRes > resolution) { console.log('need to resize...'); // Calculate new dimensions const newSize = longestDimension == 'width' ? Math.floor(oldHeight / oldWidth * resolution) : Math.floor(oldWidth / oldHeight * resolution); const newWidth = longestDimension == 'width' ? resolution : newSize; const newHeight = longestDimension == 'height' ? resolution : newSize; console.log('new width / height', newWidth, newHeight); // Create a temporary canvas to draw the downscaled image on. const canvas = document.createElement('canvas'); canvas.width = newWidth; canvas.height = newHeight; |
if you want to conserve original height and width then we can skip this part of code .
->To reduce quality without compromising with its height and width :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const image = await getImage(dataUrl); const oldWidth = image.naturalWidth; const oldHeight = image.naturalHeight; console.log('dims', oldWidth, oldHeight); // Create a temporary canvas to draw the downscaled image on. const canvas = document.createElement('canvas'); canvas.width = oldWidth; canvas.height = oldHeight; // Draw the downscaled image on the canvas and return the new data URL. const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0, oldWidth, oldHeight); const newDataUrl = canvas.toDataURL(imageType, quality); return newDataUrl; |
->Complete code for compressing image without changing its width and height :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
function getImage(dataUrl) { return new Promise((resolve, reject) => { const image = new Image(); image.src = dataUrl; image.onload = () => { resolve(image); }; image.onerror = (el, err) => { reject(err.error); }; }); } async function downscaleImage( dataUrl, imageType, // e.g. 'image/jpeg' quality // e.g. 0.9 = 90% quality ) { // Create a temporary image so that we can compute the height of the image. const image = await getImage(dataUrl); const oldWidth = image.naturalWidth; const oldHeight = image.naturalHeight; console.log('dims', oldWidth, oldHeight); // Create a temporary canvas to draw the downscaled image on. const canvas = document.createElement('canvas'); canvas.width = oldWidth; canvas.height = oldHeight; // Draw the downscaled image on the canvas and return the new data URL. const ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0, oldWidth, oldHeight); const newDataUrl = canvas.toDataURL(imageType, quality); return newDataUrl; } let dataUrl = 'data:'+fileInput1.files['0'].type+';base64,'+fileInput1.value[0]; let imageType = fileInput1.files['0'].type let quality = .3 let ds = downscaleImage( dataUrl, imageType, // e.g. 'image/jpeg' quality // e.g. 0.9 = 90% quality ) return ds |
Results :
Original Image :
Size : 130.9 kB
Compressed Image :
Size : 109.4 kB Quality : 0.8 (80% of original image…)
Compressed Image :
Size : 41.6 kB Quality : 0.3 (30% of original image…)
Related content
Auriga: Leveling Up for Enterprise Growth!
Auriga’s journey began in 2010 crafting products for India’s