文档扫描与图像处理

如何使用JavaScript压缩图像

在浏览器端压缩图像是一个有用的操作。它可以提高上传性能、节省存储空间。在本文中,我们将讨论如何使用Dynamsoft Document Viewer SDK用JavaScript压缩图像。

我们可以通过更改以下方面来压缩图像:

  • 分辨率
  • 颜色深度
  • 图像格式
  • 图像质量

在线demo

新建HTML页面

创建包含以下内容的新页面:

<!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>

添加Dynamsoft Document Viewer

Dynamsoft Document Viewer为文档扫描提供了多个组件。它支持多种图像处理方法和图像格式,我们可以用它来压缩图像。让我们把它添加到页面中。

  1. 包括Dynamsoft Document Viewer的CSS和JavaScript文件

    <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. 设置许可证。可以在此处申请许可证

    //one-day trial license
    let license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ==";
    Dynamsoft.DDV.Core.license = license;
    
  3. 初始化库。

    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. 创建doc实例,用于加载和保存图像文件。

    let doc;
    const docManager = Dynamsoft.DDV.documentManager;
    doc = docManager.createDocument();
    
  5. 从blob加载图像,用于之后的处理。

    await doc.loadSource(imgBlob);
    

降低分辨率

降低分辨率可以显著缩小尺寸。

代码:

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, {});
}

例子:

分辨率

512x512分辨率的lena.png,分辨率改到256x256后,大小从482KB降到了110KB。

降低色彩深度

我们可以将图像转换为8位灰度图像或1位黑白图像以减小大小。

代码:

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, {});
}

例子:

灰度

黑白

lena.png文件可从482KB的文件缩小为200KB的灰度文件或11KB的黑白文件。

降低图像质量

某些图像格式(如JPEG )支持设置图像质量。它会降低图像质量以减小尺寸。如果质量没有设置得太小,图像将不会有明显的变化,但可以缩小尺寸。

代码:

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

例子:

图像质量

使用0.1质量,lena.jpg文件可从125KB的文件减少到10KB的文件。

使用压缩率较高的图像格式

我们可以使用多种图像格式或压缩算法来压缩图像。后四个主要用于压缩PDF文件。

  • JPEG - 一种有损图像算法
  • PNG - 一种支持无损数据压缩的光栅图形文件格式
  • WebP - 一种现代图像格式,可为网络图像提供卓越的无损和有损压缩功能
  • JP2000 - 更现代的JPEG替代方案
  • CCITT-4 (FAX4) - 用于单色图像
  • JBIG2 - CCITT压缩单色图像的替代方案
  • LZW - 用于压缩文本和图像

代码:

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;
  })
}

压缩测试

下面是使用以下图像,用不同参数压缩图像的测试结果:链接

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

源代码

可以在以下仓库中找到所有代码和在线演示:

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