上传和下载图像是web应用中的一个是十分常见的交互功能,随着移动设备上摄像头的分辨率不断提高。上传图片是一件高资源消耗的任务,有时候一张手机图片会大于10M,所以作为开发人员,我们应该在上传到服务器之前就将图片进行一次压缩,今天给大家带来的压缩方法是纯js实现,并非用第三方压缩工具
上传图片
- 使用input上传图片
// 上传图片
<input id="img-input" type="file" accept="image/*" style="display:block" />
- 获取上传图片文件
// 获取上传图片文件
const input = document.getElementById(‘input’);
input.onChange = function(ev) {
const file = ev.target.files[0];
};
- 创建URL
// 前端指北 js压缩图片及调整大小
const blobURL = window.URL.createObjectURL(file)
- 创建img对象并赋值url
// 前端指北 js压缩图片及调整大小
const img = new Image()
img.src = blobURL
- 使用onload来处理图像
// 前端指北 js压缩图片及调整大小
img.onload = function (ev) {
window.URL.revokeObjectURL(blobURL)
}
- 创建一个canvas元素,将图片的宽高设置为画布的宽高
// 前端指北 js压缩图片及调整大小
const canvas = document.createElement(‘canvas’);
canvas.width = newWidth;
canvas.height = newHeight;
- 在画布上绘制图像
// 前端指北 js压缩图片及调整大小
const ctx = canvas.getContext(‘2d’);
ctx.drawImage(img, 0, 0, newWidth, newHeight);
- 输出自定义质量图像
// 前端指北 js压缩图片及调整大小
canvas.toBlob(
function (blob) {
// Handle the compressed image
},
mimeType,
quality
)
mimeType 是图像的类型,如 image/jpeg、 image/png。quality值范围从0到1,表示输出图像的质量。
最终代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="root">
<p>上传一张图片试试</p>
<input
id="img-input"
type="file"
accept="image/*"
style="display: block"
/>
</div>
<script>
const MAX_WIDTH = 320;
const MAX_HEIGHT = 180;
const MIME_TYPE = 'image/jpeg';
const QUALITY = 0.7;
const input = document.getElementById('img-input');
input.onchange = function (ev) {
const file = ev.target.files[0];
const blobURL = URL.createObjectURL(file);
const img = new Image();
img.src = blobURL;
img.onerror = function () {
URL.revokeObjectURL(this.src);
console.log('无法加载图像');
};
img.onload = function () {
URL.revokeObjectURL(this.src);
const [newWidth, newHeight] = calculateSize(
img,
MAX_WIDTH,
MAX_HEIGHT
);
const canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, newWidth, newHeight);
canvas.toBlob(
(blob) => {
displayInfo('原文件大小', file);
displayInfo('压缩后', blob);
},
MIME_TYPE,
QUALITY
);
document.getElementById('root').append(canvas);
};
};
function calculateSize(img, maxWidth, maxHeight) {
let width = img.width;
let height = img.height;
// calculate the width and height, constraining the proportions
if (width > height) {
if (width > maxWidth) {
height = Math.round((height * maxWidth) / width);
width = maxWidth;
}
} else {
if (height > maxHeight) {
width = Math.round((width * maxHeight) / height);
height = maxHeight;
}
}
return [width, height];
}
function displayInfo(label, file) {
const p = document.createElement('p');
p.innerText = `${label} - ${readableBytes(file.size)}`;
document.getElementById('root').append(p);
}
function readableBytes(bytes) {
const i = Math.floor(Math.log(bytes) / Math.log(1024)),
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
}
</script>
</body>
</html>