1、 Canvas 的绘图能力,通过调整图片的分辨率或者绘图质量来达到图片压缩的效果,实现思路如下:
- 获取上传 Input 中的图片对象 File
- 将图片转换成 base64 格式
- base64 编码的图片通过 Canvas 转换压缩,这里会用到的 Canvas 的 drawImage 以及 toDataURL 这两个 Api,一个调节图片的分辨率的,一个是调节图片压缩质量并且输出的,后续会有详细介绍
- 转换后的图片生成对应的新图片,然后输出
2、代码实现
<body>
<input type="file" name="image" id="dealImg">
<button type="submit" id="upload">提交</button>
<button onclick="downloadImg()">兼容 IE 下载</button>
<img class="img" id="compressImg"/>
<script>
var sub = document.getElementById("upload");
sub.onclick = function () {
var dealImg = document.getElementById("dealImg").files[0];
var type = dealImg.type;
handleCompressImage(dealImg, type)
}
function handleCompressImage(img, type) {
let reader = new FileReader();
// 读取文件
reader.readAsDataURL(img);
reader.onload = function (e) {
let image = new Image(); //新建一个img标签
image.src = e.target.result;
image.onload = function () {
let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
// 定义 canvas 大小,也就是压缩后下载的图片大小
let imageWidth = 300; //压缩后图片的大小
let imageHeight = 200;
canvas.width = imageWidth;
canvas.height = imageHeight;
// 图片不压缩,全部加载展示
context.drawImage(image, 0, 0, imageWidth,imageHeight);
console.log(context)
// 图片按压缩尺寸载入
// let imageWidth = 500; //压缩后图片的大小
// let imageHeight = 200;
// context.drawImage(image, 0, 0, 500, 200);
// 图片去截取指定位置载入
// context.drawImage(image,100, 100, 100, 100, 0, 0, imageWidth, imageHeight);
document.getElementById("compressImg").src = canvas.toDataURL(`image/${type}`);
// };
};
}
}
// base64 图片转 blob 后下载
function downloadImg() {
let parts = document.getElementById("compressImg").src.split(';base64,');
console.log(parts)
let contentType = parts[0].split(':')[1];
console.log(contentType)
let raw = window.atob(parts[1]);
let rawLength = raw.length;
let uInt8Array = new Uint8Array(rawLength);
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
const blob = new Blob([uInt8Array], {
type: contentType
});
this.compressImg = URL.createObjectURL(blob);
if (window.navigator.msSaveOrOpenBlob) {
// 兼容 ie 的下载方式
window.navigator.msSaveOrOpenBlob(blob, dealImg.name);
} else {
var dealImg = document.getElementById("dealImg").files[0];
const a = document.createElement('a');
a.href = this.compressImg;
a.setAttribute('download',dealImg.name);
a.click();
}
}
</script>
</body>
代码解析:
读取文件的时候,新建一个image元素,把src赋值为文件流的target.result;当图片加载的时候,用canvas来绘制图形
建立一个 Image
对象,一个 canvas
画布,设定自己想要下载的图片尺寸,调用 drawImage
方法在 canvas 中绘制上传的图片
,最后用调用 canvas
的 toDataURL
方法可以输出 base64 格式的图片;
canvas.toDataURL(`image/${type}`)
base-64 解码使用方法是 atob()。
window.atob(encodedStr)
unit8Array
new Uint8Array(length)
静态方法会创建一个 DOMString。用于创建 URL 的 File 对象、Blob 对象或者 MediaSource 对象。
URL.createObjectURL(blob);
A标签的下载
<a download="filename" href="href"> 下载 </a>
3、下载的图片大小