参考:https://blog.youkuaiyun.com/qdm13209211861/article/details/126668206
参考代码在获取base64的时候有图片失真的问题。下面的代码已经修复,希望对你有帮助。
<html>
<script src="https://cdn.bootcdn.net/ajax/libs/jszip/3.10.0/jszip.min.js">
</script>
<script src="https://cdn.bootcdn.net/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js">
</script>
<body>
<div id="picList">
<img src="https://profile-avatar.csdnimg.cn/default.jpg" alt="">
<img src="https://profile-avatar.csdnimg.cn/default.jpg" alt="">
<img src="https://profile-avatar.csdnimg.cn/default.jpg" alt="">
</div>
</body>
<script>
//获取所有子节点,也就是img标签
var box = document.getElementById('picList').childNodes
var imgList = []
for (var i = 0; i < box.length; i++) {
if (box[i].src) {
imgList.push(box[i].src)
}
}
downloadZipImage(imgList, '下载文件的名称')
function getSuffix(url) {
return url.split('?')[0].replace(/.+\./, "").toLowerCase()
}
function getBase64ImageUrl(url, callBack, imgType) {
var suffix = getSuffix(url)
if (!imgType) {
imgType = "image/" + suffix;
}
var xhr = new XMLHttpRequest();
xhr.responseType = "arraybuffer";
xhr.open('GET', url, true);
xhr.onload = function() {
var result = xhr.response;
var file = new File([result], "foo." + imgType.match(/\/([A-Za-z]+)/)[1], {
type: imgType,
});
var reader = new FileReader();
reader.onload = function(evt) {
callBack(evt.target.result);
};
reader.readAsDataURL(file)
}
xhr.send(null);
}
/**
* 下载压缩图片
* @param {any[]} imgArr 图片合集
* @param {string} imgKey 如果不是单纯的图片路径 需要传入路径的key
*/
function downloadZipImage(imgArr, downloadName = 'img', imgKey = '') {
if (!imgArr || !imgArr.length) {
return;
}
const zip = new JSZip();
// 创建images文件夹
const imgFolder = zip.folder('images');
let index = 0; // 判断加载了几张图片的标识
for (let i = 0; i < imgArr.length; i++) {
const itemImg = imgKey ? imgArr[i][imgKey] : imgArr[i];
/**
* 如果是Base64就不需要再做异步处理了
*/
const Base64Img = getBase64(itemImg);
let suffix = getSuffix(itemImg)
if (Base64Img['then']) {
Base64Img['then'](function(base64) {
setBase64Img(zip, imgFolder, base64, imgArr, index, downloadName, suffix);
index++;
}, function(err) {
console.log(err); //打印异常信息
});
} else {
setBase64Img(zip, imgFolder, Base64Img, imgArr, index, downloadName, suffix);
index++;
}
}
}
/**
* 将图片转换成base64 并返回路径
* @param img
* @param {number} width 调用时传入具体像素值,控制大小 ,不传则默认图像大小
* @param {number} height
* @returns {string}
*/
function getBase64Image(img, width = 0, height = 0) {
const canvas = document.createElement('canvas');
canvas.width = width ? width : img.width;
canvas.height = height ? height : img.height;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
const dataURL = canvas.toDataURL();
return dataURL;
}
/**
* 检查是不是Base64
* @param img
* @returns {boolean}
*/
function IsBase64(img) {
const _img = img.toLowerCase();
if (_img.endsWith('jpg') || _img.endsWith('jpeg') || _img.endsWith('png') || _img.endsWith('gif'))
return false;
return true;
}
/**
* 加载图片 加载成功后经图片返回
* @param img
* @param isCanvas 使用canvas获取base64 有被压缩和放大的问题; 默认通过XMLHttpRequest获取arraybuffer能保持文件原始数据
* @returns {Promise<any>}
*/
function getBase64(img, isCanvas) {
let url = '';
let suffix = getSuffix(img)
if (IsBase64(img)) {
// 有一些数据 后台没有返回前缀
const _base64 = 'data:image/' + suffix + ';base64,';
if (img.startsWith(_base64)) {
url = img;
} else {
url = _base64 + img;
}
return url;
} else {
url = img;
const image = new Image();
image.crossOrigin = '*';
image.src = url;
return new Promise(function(resolve, reject) {
image.onload = function() {
if (isCanvas) {
resolve(getBase64Image(image)); //将base64传给done上传处理
} else {
getBase64ImageUrl(url, base64 => {
resolve(base64)
})
}
}
});
}
}
/**
* 压缩图片
*/
function setBase64Img(zip, imgFolder, base64, imgArr, index, downloadName, suffix) {
suffix = suffix ? suffix : 'png'
base64 = base64.split('base64,')[1];
imgFolder.file(index + '.' + suffix, base64, {
base64: true
});
if (index === imgArr.length - 1) {
zip.generateAsync({
type: 'blob'
}).then((blob) => {
saveAs(blob, downloadName + '.zip');
// getZipFiles(blob)
});
}
}
</script>
</html>