压缩图片

198 阅读2分钟
// 压缩图片
/**
 * 图片
 * @param file file类型的图片
 * @param callBack 回调函数
 */
function compressImg(file,callBack){
    // console.log(file)
    // 判断浏览器 IE暂不支持
    if(navigator.userAgent.indexOf('Edge') > -1 || navigator.userAgent.indexOf('Trident') > -1){
        callBack({ret:1,msg:'IE浏览器暂时不支持图片压缩,请使用chrome或firefox浏览器 !'})
         return false
    }
    // 非图片文件直接返回
    if(file.type.indexOf('image') < 0){
        callBack({
             ret:0,
             file:file
        })
        return false
    }
    // 读取文件
    let reader = new FileReader();
    reader.onload = e => {
        let result = e.target.result
        let img = new Image()
        img.src = result
        img.onload = ()=>{
            // console.log('********未压缩前的图片大小********')
            // console.log(result.length / 1024)
            // console.log(img.width)
            // console.log(img.height)
            if(img.width > 1024 || img.height > 1024){
                // 0.6为压缩的程度,数值越小,压缩的文件越小,图片也会越模糊
                let blobImg = dataURLtoBlob(start(img, 1))
                let newFile = new File([blobImg], file.name, {type:'image/jpeg'})
                callBack({
                    ret:0,
                    file:newFile
                })
            } else {
                 callBack({
                 ret:0,
                    file:file
                })
            }
        }
    };
    // 读取图像
    reader.readAsDataURL(file);
}

/**
 * 开始压缩图片
 * @param img 图片 url类型
 * @param quclity 被压缩图片的质量
 * @returns {string} 返回base64
 */
function start(img,quclity){
	let canvas = document.createElement('canvas')
	let ctx = canvas.getContext('2d')
	// 图片原始宽高
	let imgWidth = img.width
	let imgHeight = img.height
	// 修正后的高宽
	let fixWidth;
	let fixHeight;
	if(imgWidth - imgHeight > 0){
            if(imgWidth > 1024){
                fixHeight = (imgHeight/imgWidth)*1024
                fixWidth = 1024
            }
	} else {
            if(imgHeight > 1024){
                fixWidth = (imgWidth/imgHeight)*1024
                fixHeight = 1024
            }
	}
	canvas.width = fixWidth
	canvas.height = fixHeight
	// 铺底色
	// ctx.fillStyle = '#fff'
	ctx.fillRect(0, 0, canvas.width, canvas.height)
	ctx.drawImage(img, 0, 0, fixWidth, fixHeight)
	// console.log('*******压缩后的图片大小*******')
	let ndata = canvas.toDataURL('image/jpeg', quclity)
	// console.log(ndata.length / 1024)
	return ndata
}
// base转blob
function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
		bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type: mime});
}
exports.compressImg = compressImg;


// 压缩图片
compressImg(data, (result) => {
    if (result.ret === 0) {
        let formData = new FormData();
        formData.append('file', result.file);
        postImg('/api/file/upload_img', formData).then((res) => {
            res['file'] = result.file;
            resolve(res);
        }).catch((res) => {
            reject(res);
        });
    } else {
        resolve(result);
    }
});
		

压缩图片主要运用的是canvas技术。

  • 首先,创建一个canvas对象。
  • 使用fillRect填充底色
  • 使用drawImage绘制图片
  • 使用toDataURL导出图片,toDataURL属性可以接收一个参数,用来决定图片的质量,这个值在0-1之间,数值越小,压缩的文件越小,图片也会越模糊
  • canvas返回的图片类型是base64。
  • 使用dataURLtoBlob将base64转换为blob类型
  • 使用 new File将blob转换为File类型(IE不支持new File)