How to Compress an Image with JavaScript

Image compressing on the browser is a useful operation. It can improve the uploading performance and save the storage. In this article, we are going to talk about how to compress an image with JavaScript using the Dynamsoft Document Viewer SDK.

We can compress an image by changing the following aspects:

  • Resolution
  • Color depth
  • Image format
  • Image quality

Online demo

New HTML Page

Create a new page with the following content:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <title>Image Compression</title>
  <style>
  </style>
</head>
<body>
</body>
<script>
</script>
</html>

Add Dynamsoft Document Viewer

Dynamsoft Document Viewer provides a set of viewers for document scanning. It supports a bunch of image processing methods and image formats we can use to compress an image. Let’s add it to the page to use it.

  1. Include the CSS and JavaScript files of Dynamsoft Document Viewer

    <script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@1.1.0/dist/ddv.js"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@1.1.0/dist/ddv.css">
    
  2. Set the license. You can apply for a license here.

    let license = "LICENSE-KEY";
    Dynamsoft.DDV.Core.license = license;
    
  3. Init the library.

    Dynamsoft.DDV.Core.engineResourcePath = "https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@1.1.0/dist/engine";// Lead to a folder containing the distributed WASM files
    await Dynamsoft.DDV.Core.init();
    
  4. Create a doc instance for loading and saving image files.

    let doc;
    const docManager = Dynamsoft.DDV.documentManager;
    doc = docManager.createDocument();
    
  5. Load an image from blob waiting for processing.

    await doc.loadSource(imgBlob);
    

Reduce the Resolution

Reducing the resolution can achieve siginificant size reduction.

Code:

function resize(newWidth, newHeight){
  const pageUid = doc.pages[0];
  const pageData = await doc.getPageData(pageUid)
  const imageProcess = Dynamsoft.DDV.Experiments.get("ImageProcess");
  const result = await imageProcess.process({type:3, data:pageData.display.data}, {type:13/*resize*/, params:{newWidth:newWidth, newHeight:newHeight, mode:2}});
  const newImage = new Blob([result.output],{type:result.outputContentType});
  await doc.updatePage(pageUid, newImage, {});
}

Example:

resolution

The 512x512 lena.png file is reduced from 482KB to 110KB by changing the resolution to 256x256.

Reduce the Color Depth

We can convert the image to a 8-bit grayscale image or a 1-bit black and white image to reduce the size.

Code:

async function performColorConversion(type){
  const pageUid = doc.pages[0];
  const pageData = await doc.getPageData(pageUid)
  const imageProcess = Dynamsoft.DDV.Experiments.get("ImageProcess");
  const result = await imageProcess.process({type:3, data:pageData.display.data}, {type: type/*1: blackAndWhite 2: gray*/, params:{saveInk:false, level:1}});
  const newImage = new Blob([result.output],{type:result.outputContentType});
  await doc.updatePage(pageUid, newImage, {});
}

Example:

grayscale

black and white

The lena.png file can be reduced from a 482KB file to a 200KB grayscale file or a 11KB black and white file.

Reduce the Image Quality

Some image formats like JPEG support setting the image quality. It will degrade the image quality to reduce the size. If the quality is not set too small, the image will not have perceptible changes but the size can be reduced.

Code:

let blob = await doc.saveToJpeg(0,{quality: 50});

Example:

image quality

The lena.jpg file can be reduced from a 125KB file to a 10KB file using the 0.1 quality.

Use an Image Format with a Higher Compression Rate

There are various image formats or compression algorithms we can use. The latter four are mainly used for compressing PDF files.

  • JPEG - a lossy algorithm for images
  • PNG - a raster-graphics file format that supports lossless data compression
  • WebP - a modern image format that provides superior lossless and lossy compression for images on the web
  • JP2000 - a more modern alternative to JPEG
  • CCITT-4 (FAX4) - used for monochrome images
  • JBIG2 - an alternative to CCITT compression for monochrome images
  • LZW - used for compressing text as well as images

Code:

let blob;
let quality = 1.0;
let imageFormat = "image/webp";
const isPDF = imageFormat.indexOf("pdf") != -1;
if (imageFormat === "image/png") {
  blob = await doc.saveToPng(0,{});
}else if (imageFormat === "image/jpeg") {
  blob = await doc.saveToJpeg(0,{quality: quality*100});
  console.log({quality: quality*100});
}else if (imageFormat === "image/webp") {
  let pngBlob = await doc.saveToPng(0,{});
  blob = await convertBlobToWebP(pngBlob,quality);
}else if (isPDF) {
  blob = await doc.saveToPdf([0],{quality: quality*100,compression:imageFormat});
}

function convertBlobToWebP(blob,quality){
  return new Promise((resolve, reject) => {
    const url = URL.createObjectURL(blob);
    let tmpImg = document.createElement("img");
    tmpImg.onload = function(){
      let width = tmpImg.naturalWidth;
      let height = tmpImg.naturalHeight;
      let context = canvas.getContext('2d');
      canvas.width = width;
      canvas.height = height;
      context.drawImage(tmpImg, 0, 0, tmpImg.naturalWidth, tmpImg.naturalHeight, 0, 0, canvas.width, canvas.height);
      canvas.toBlob((blob)=>{
        resolve(blob);
      },"image/webp",quality)
    }
    tmpImg.src = url;
  })
}

Compression Test

Here is a table of the test result compressing the images with different parameters of this image: link.

Color Conversion Image Format Quality Size Time Elapsed Compression Rate
No conversionimage/png19506.63KB1763ms440.60%
No conversionimage/jpeg0.1272.04KB580ms12.61%
No conversionimage/jpeg0.2326.59KB613ms15.14%
No conversionimage/jpeg0.3375.83KB581ms17.42%
No conversionimage/jpeg0.4428.28KB598ms19.85%
No conversionimage/jpeg0.5498.50KB618ms23.10%
No conversionimage/jpeg0.6576.01KB608ms26.70%
No conversionimage/jpeg0.7750.01KB590ms34.76%
No conversionimage/jpeg0.81069.88KB590ms49.59%
No conversionimage/jpeg0.91827.61KB604ms84.70%
No conversionimage/jpeg14049.13KB635ms187.66%
No conversionimage/webp0.1103.14KB2869ms4.78%
No conversionimage/webp0.2119.90KB2804ms5.56%
No conversionimage/webp0.3137.97KB2912ms6.39%
No conversionimage/webp0.4162.52KB2816ms7.53%
No conversionimage/webp0.5189.29KB2951ms8.77%
No conversionimage/webp0.6218.95KB2886ms10.15%
No conversionimage/webp0.7245.80KB2852ms11.39%
No conversionimage/webp0.8355.04KB2946ms16.45%
No conversionimage/webp0.9817.46KB3029ms37.89%
No conversionimage/webp15964.65KB4900ms276.44%
No conversionpdf/jbig211070.78KB684ms49.63%
No conversionpdf/fax411070.78KB613ms49.63%
No conversionpdf/jp20000.11.11KB2398ms0.05%
No conversionpdf/jp20000.21.51KB2612ms0.07%
No conversionpdf/jp20000.335.31KB2599ms1.64%
No conversionpdf/jp20000.4239.69KB2550ms11.11%
No conversionpdf/jp20000.51976.63KB2592ms91.61%
No conversionpdf/jp20000.63915.27KB2570ms181.46%
No conversionpdf/jp20000.74577.19KB2568ms212.14%
No conversionpdf/jp20000.84782.33KB2551ms221.65%
No conversionpdf/jp20000.94836.04KB2547ms224.13%
No conversionpdf/jp200014843.24KB2550ms224.47%
No conversionpdf/lzw19142.31KB1243ms423.72%
Grayscaleimage/png16001.92KB573ms278.17%
Grayscaleimage/jpeg0.1224.03KB268ms10.38%
Grayscaleimage/jpeg0.2277.29KB262ms12.85%
Grayscaleimage/jpeg0.3327.86KB258ms15.20%
Grayscaleimage/jpeg0.4388.02KB266ms17.98%
Grayscaleimage/jpeg0.5407.98KB260ms18.91%
Grayscaleimage/jpeg0.6777.40KB272ms36.03%
Grayscaleimage/jpeg0.7951.35KB284ms44.09%
Grayscaleimage/jpeg0.81012.78KB278ms46.94%
Grayscaleimage/jpeg0.91406.44KB283ms65.18%
Grayscaleimage/jpeg13213.54KB313ms148.94%
Grayscaleimage/webp0.198.02KB1419ms4.54%
Grayscaleimage/webp0.2117.39KB1473ms5.44%
Grayscaleimage/webp0.3136.96KB1439ms6.35%
Grayscaleimage/webp0.4162.58KB1466ms7.53%
Grayscaleimage/webp0.5191.67KB1483ms8.88%
Grayscaleimage/webp0.6225.83KB1539ms10.47%
Grayscaleimage/webp0.7257.49KB1504ms11.93%
Grayscaleimage/webp0.8391.60KB1611ms18.15%
Grayscaleimage/webp0.9856.50KB1717ms39.70%
Grayscaleimage/webp15990.37KB3264ms277.63%
Grayscalepdf/jbig211013.68KB418ms46.98%
Grayscalepdf/fax411013.68KB335ms46.98%
Grayscalepdf/jp20000.11.09KB1429ms0.05%
Grayscalepdf/jp20000.21.49KB1428ms0.07%
Grayscalepdf/jp20000.335.25KB1425ms1.63%
Grayscalepdf/jp20000.4247.83KB1447ms11.49%
Grayscalepdf/jp20000.51759.55KB1459ms81.55%
Grayscalepdf/jp20000.63337.76KB1499ms154.69%
Grayscalepdf/jp20000.73816.45KB1461ms176.88%
Grayscalepdf/jp20000.83878.43KB1488ms179.75%
Grayscalepdf/jp20000.93884.98KB1466ms180.06%
Grayscalepdf/jp200013885.36KB1460ms180.07%
Grayscalepdf/lzw15301.60KB476ms245.71%
Black & whiteimage/png1130.18KB115ms6.03%
Black & whiteimage/jpeg0.1363.82KB374ms16.86%
Black & whiteimage/jpeg0.2472.41KB190ms21.89%
Black & whiteimage/jpeg0.3570.84KB192ms26.46%
Black & whiteimage/jpeg0.4642.30KB191ms29.77%
Black & whiteimage/jpeg0.5706.09KB192ms32.72%
Black & whiteimage/jpeg0.6771.68KB195ms35.76%
Black & whiteimage/jpeg0.7855.62KB198ms39.66%
Black & whiteimage/jpeg0.8974.84KB194ms45.18%
Black & whiteimage/jpeg0.91222.58KB195ms56.66%
Black & whiteimage/jpeg12258.45KB215ms104.67%
Black & whiteimage/webp0.1290.87KB1037ms13.48%
Black & whiteimage/webp0.2327.36KB1057ms15.17%
Black & whiteimage/webp0.3352.60KB832ms16.34%
Black & whiteimage/webp0.4378.89KB856ms17.56%
Black & whiteimage/webp0.5396.79KB875ms18.39%
Black & whiteimage/webp0.6416.35KB869ms19.30%
Black & whiteimage/webp0.7432.61KB858ms20.05%
Black & whiteimage/webp0.8469.18KB868ms21.74%
Black & whiteimage/webp0.9543.33KB889ms25.18%
Black & whiteimage/webp1107.07KB259ms4.96%
Black & whitepdf/jbig2158.00KB198ms2.69%
Black & whitepdf/fax41127.27KB124ms5.90%
Black & whitepdf/jp20000.158.00KB185ms2.69%
Black & whitepdf/jp20000.258.00KB189ms2.69%
Black & whitepdf/jp20000.358.00KB175ms2.69%
Black & whitepdf/jp20000.458.00KB185ms2.69%
Black & whitepdf/jp20000.558.00KB176ms2.69%
Black & whitepdf/jp20000.658.00KB175ms2.69%
Black & whitepdf/jp20000.758.00KB177ms2.69%
Black & whitepdf/jp20000.858.00KB189ms2.69%
Black & whitepdf/jp20000.958.00KB177ms2.69%
Black & whitepdf/jp2000158.00KB184ms2.69%
Black & whitepdf/lzw1127.27KB110ms5.90%

Source Code

You can find all the code and an online demo in the following repo:

https://github.com/tony-xlh/image-compression-javascript