在浏览器端压缩图像是一个有用的操作。它可以提高上传性能、节省存储空间。在本文中,我们将讨论如何使用Dynamsoft Document Viewer SDK用JavaScript压缩图像。
我们可以通过更改以下方面来压缩图像:
- 分辨率
- 颜色深度
- 图像格式
- 图像质量
新建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为文档扫描提供了多个组件。它支持多种图像处理方法和图像格式,我们可以用它来压缩图像。让我们把它添加到页面中。
-
包括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">
-
设置许可证。可以在此处申请许可证。
//one-day trial license let license = "DLS2eyJoYW5kc2hha2VDb2RlIjoiMjAwMDAxLTE2NDk4Mjk3OTI2MzUiLCJvcmdhbml6YXRpb25JRCI6IjIwMDAwMSIsInNlc3Npb25QYXNzd29yZCI6IndTcGR6Vm05WDJrcEQ5YUoifQ=="; Dynamsoft.DDV.Core.license = license;
-
初始化库。
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();
-
创建doc实例,用于加载和保存图像文件。
let doc; const docManager = Dynamsoft.DDV.documentManager; doc = docManager.createDocument();
-
从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/png | 1 | 9506.63KB | 1763ms | 440.60% |
不做转换 | image/jpeg | 0.1 | 272.04KB | 580ms | 12.61% |
不做转换 | image/jpeg | 0.2 | 326.59KB | 613ms | 15.14% |
不做转换 | image/jpeg | 0.3 | 375.83KB | 581ms | 17.42% |
不做转换 | image/jpeg | 0.4 | 428.28KB | 598ms | 19.85% |
不做转换 | image/jpeg | 0.5 | 498.50KB | 618ms | 23.10% |
不做转换 | image/jpeg | 0.6 | 576.01KB | 608ms | 26.70% |
不做转换 | image/jpeg | 0.7 | 750.01KB | 590ms | 34.76% |
不做转换 | image/jpeg | 0.8 | 1069.88KB | 590ms | 49.59% |
不做转换 | image/jpeg | 0.9 | 1827.61KB | 604ms | 84.70% |
不做转换 | image/jpeg | 1 | 4049.13KB | 635ms | 187.66% |
不做转换 | image/webp | 0.1 | 103.14KB | 2869ms | 4.78% |
不做转换 | image/webp | 0.2 | 119.90KB | 2804ms | 5.56% |
不做转换 | image/webp | 0.3 | 137.97KB | 2912ms | 6.39% |
不做转换 | image/webp | 0.4 | 162.52KB | 2816ms | 7.53% |
不做转换 | image/webp | 0.5 | 189.29KB | 2951ms | 8.77% |
不做转换 | image/webp | 0.6 | 218.95KB | 2886ms | 10.15% |
不做转换 | image/webp | 0.7 | 245.80KB | 2852ms | 11.39% |
不做转换 | image/webp | 0.8 | 355.04KB | 2946ms | 16.45% |
不做转换 | image/webp | 0.9 | 817.46KB | 3029ms | 37.89% |
不做转换 | image/webp | 1 | 5964.65KB | 4900ms | 276.44% |
不做转换 | pdf/jbig2 | 1 | 1070.78KB | 684ms | 49.63% |
不做转换 | pdf/fax4 | 1 | 1070.78KB | 613ms | 49.63% |
不做转换 | pdf/jp2000 | 0.1 | 1.11KB | 2398ms | 0.05% |
不做转换 | pdf/jp2000 | 0.2 | 1.51KB | 2612ms | 0.07% |
不做转换 | pdf/jp2000 | 0.3 | 35.31KB | 2599ms | 1.64% |
不做转换 | pdf/jp2000 | 0.4 | 239.69KB | 2550ms | 11.11% |
不做转换 | pdf/jp2000 | 0.5 | 1976.63KB | 2592ms | 91.61% |
不做转换 | pdf/jp2000 | 0.6 | 3915.27KB | 2570ms | 181.46% |
不做转换 | pdf/jp2000 | 0.7 | 4577.19KB | 2568ms | 212.14% |
不做转换 | pdf/jp2000 | 0.8 | 4782.33KB | 2551ms | 221.65% |
不做转换 | pdf/jp2000 | 0.9 | 4836.04KB | 2547ms | 224.13% |
不做转换 | pdf/jp2000 | 1 | 4843.24KB | 2550ms | 224.47% |
不做转换 | pdf/lzw | 1 | 9142.31KB | 1243ms | 423.72% |
灰度 | image/png | 1 | 6001.92KB | 573ms | 278.17% |
灰度 | image/jpeg | 0.1 | 224.03KB | 268ms | 10.38% |
灰度 | image/jpeg | 0.2 | 277.29KB | 262ms | 12.85% |
灰度 | image/jpeg | 0.3 | 327.86KB | 258ms | 15.20% |
灰度 | image/jpeg | 0.4 | 388.02KB | 266ms | 17.98% |
灰度 | image/jpeg | 0.5 | 407.98KB | 260ms | 18.91% |
灰度 | image/jpeg | 0.6 | 777.40KB | 272ms | 36.03% |
灰度 | image/jpeg | 0.7 | 951.35KB | 284ms | 44.09% |
灰度 | image/jpeg | 0.8 | 1012.78KB | 278ms | 46.94% |
灰度 | image/jpeg | 0.9 | 1406.44KB | 283ms | 65.18% |
灰度 | image/jpeg | 1 | 3213.54KB | 313ms | 148.94% |
灰度 | image/webp | 0.1 | 98.02KB | 1419ms | 4.54% |
灰度 | image/webp | 0.2 | 117.39KB | 1473ms | 5.44% |
灰度 | image/webp | 0.3 | 136.96KB | 1439ms | 6.35% |
灰度 | image/webp | 0.4 | 162.58KB | 1466ms | 7.53% |
灰度 | image/webp | 0.5 | 191.67KB | 1483ms | 8.88% |
灰度 | image/webp | 0.6 | 225.83KB | 1539ms | 10.47% |
灰度 | image/webp | 0.7 | 257.49KB | 1504ms | 11.93% |
灰度 | image/webp | 0.8 | 391.60KB | 1611ms | 18.15% |
灰度 | image/webp | 0.9 | 856.50KB | 1717ms | 39.70% |
灰度 | image/webp | 1 | 5990.37KB | 3264ms | 277.63% |
灰度 | pdf/jbig2 | 1 | 1013.68KB | 418ms | 46.98% |
灰度 | pdf/fax4 | 1 | 1013.68KB | 335ms | 46.98% |
灰度 | pdf/jp2000 | 0.1 | 1.09KB | 1429ms | 0.05% |
灰度 | pdf/jp2000 | 0.2 | 1.49KB | 1428ms | 0.07% |
灰度 | pdf/jp2000 | 0.3 | 35.25KB | 1425ms | 1.63% |
灰度 | pdf/jp2000 | 0.4 | 247.83KB | 1447ms | 11.49% |
灰度 | pdf/jp2000 | 0.5 | 1759.55KB | 1459ms | 81.55% |
灰度 | pdf/jp2000 | 0.6 | 3337.76KB | 1499ms | 154.69% |
灰度 | pdf/jp2000 | 0.7 | 3816.45KB | 1461ms | 176.88% |
灰度 | pdf/jp2000 | 0.8 | 3878.43KB | 1488ms | 179.75% |
灰度 | pdf/jp2000 | 0.9 | 3884.98KB | 1466ms | 180.06% |
灰度 | pdf/jp2000 | 1 | 3885.36KB | 1460ms | 180.07% |
灰度 | pdf/lzw | 1 | 5301.60KB | 476ms | 245.71% |
黑白 | image/png | 1 | 130.18KB | 115ms | 6.03% |
黑白 | image/jpeg | 0.1 | 363.82KB | 374ms | 16.86% |
黑白 | image/jpeg | 0.2 | 472.41KB | 190ms | 21.89% |
黑白 | image/jpeg | 0.3 | 570.84KB | 192ms | 26.46% |
黑白 | image/jpeg | 0.4 | 642.30KB | 191ms | 29.77% |
黑白 | image/jpeg | 0.5 | 706.09KB | 192ms | 32.72% |
黑白 | image/jpeg | 0.6 | 771.68KB | 195ms | 35.76% |
黑白 | image/jpeg | 0.7 | 855.62KB | 198ms | 39.66% |
黑白 | image/jpeg | 0.8 | 974.84KB | 194ms | 45.18% |
黑白 | image/jpeg | 0.9 | 1222.58KB | 195ms | 56.66% |
黑白 | image/jpeg | 1 | 2258.45KB | 215ms | 104.67% |
黑白 | image/webp | 0.1 | 290.87KB | 1037ms | 13.48% |
黑白 | image/webp | 0.2 | 327.36KB | 1057ms | 15.17% |
黑白 | image/webp | 0.3 | 352.60KB | 832ms | 16.34% |
黑白 | image/webp | 0.4 | 378.89KB | 856ms | 17.56% |
黑白 | image/webp | 0.5 | 396.79KB | 875ms | 18.39% |
黑白 | image/webp | 0.6 | 416.35KB | 869ms | 19.30% |
黑白 | image/webp | 0.7 | 432.61KB | 858ms | 20.05% |
黑白 | image/webp | 0.8 | 469.18KB | 868ms | 21.74% |
黑白 | image/webp | 0.9 | 543.33KB | 889ms | 25.18% |
黑白 | image/webp | 1 | 107.07KB | 259ms | 4.96% |
黑白 | pdf/jbig2 | 1 | 58.00KB | 198ms | 2.69% |
黑白 | pdf/fax4 | 1 | 127.27KB | 124ms | 5.90% |
黑白 | pdf/jp2000 | 0.1 | 58.00KB | 185ms | 2.69% |
黑白 | pdf/jp2000 | 0.2 | 58.00KB | 189ms | 2.69% |
黑白 | pdf/jp2000 | 0.3 | 58.00KB | 175ms | 2.69% |
黑白 | pdf/jp2000 | 0.4 | 58.00KB | 185ms | 2.69% |
黑白 | pdf/jp2000 | 0.5 | 58.00KB | 176ms | 2.69% |
黑白 | pdf/jp2000 | 0.6 | 58.00KB | 175ms | 2.69% |
黑白 | pdf/jp2000 | 0.7 | 58.00KB | 177ms | 2.69% |
黑白 | pdf/jp2000 | 0.8 | 58.00KB | 189ms | 2.69% |
黑白 | pdf/jp2000 | 0.9 | 58.00KB | 177ms | 2.69% |
黑白 | pdf/jp2000 | 1 | 58.00KB | 184ms | 2.69% |
黑白 | pdf/lzw | 1 | 127.27KB | 110ms | 5.90% |
源代码
可以在以下仓库中找到所有代码和在线演示: