<!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" />
<title>图片压缩,支持gif压缩(gif是取第一帧)</title>
</head>
<body>
<input id="fileInput" type="file" />
<img id="img" src="" alt="" />
<img id="blobImg" src="" alt="" />
</body>
<script>
let fileId = document.getElementById('fileInput')
let img = document.getElementById('img')
fileId.onchange = function (e) {
console.log(e)
let file = e.target.files[0] //file文件
fileToBase64(file, 0.2)
}
// 读取文件
const fileToBase64 = (file, quality) => {
console.log('将file文件通过FileReader转化为base64格式')
let fileReader = new FileReader()
let type = file.type //"image/png"
fileReader.readAsDataURL(file)
fileReader.onload = function (e) {
console.log('原始二进制字符串:', this.result.toString())
compress(fileReader.result, quality, type)
}
}
/**
* 处理base64数据,通过canvas(toDataURL)进行压缩绘制,然后输出压缩后的base64图片数据
*/
const MAX_WIDTH = 800
const compress = (base64, quality, mimeType) => {
let cvs = document.createElement('canvas')
let img = document.createElement('img')
// CORS 策略,会存在跨域问题
img.crossOrigin = 'anonymous'
return new Promise((resolve, reject) => {
img.src = base64
let offetX = 0
img.onload = () => {
if (img.width > MAX_WIDTH) {
cvs.width = MAX_WIDTH
cvs.height = (img.height * MAX_WIDTH) / img.width
offetX = (img.width - MAX_WIDTH) / 2
} else {
cvs.width = img.width
cvs.height = img.height
}
// 重点! 将图片插入画布并开始绘制
let ctx = cvs.getContext('2d').drawImage(img, 0, 0, cvs.width, cvs.height)
let imageData = cvs.toDataURL(mimeType, quality)
console.log('canvas图片压缩', imageData)
let blobData = converrVase64UrlToBlob(imageData, mimeType)
console.log('我想转成blob格式看看', blobData)
resolve(imageData)
}
})
}
/**
* base64数据转成blob文件流
* mimeType 图片类型,例如 mimeType='image/png'
*/
const converrVase64UrlToBlob = (base64, mimeType) => {
let bytes = window.atob(base64.split(',')[1]) //atob方法用于解码base64
// 创建一个长度为 bytes.length 的 buffer(一个二进制文件), 它会分配一个 16 字节(byte)的连续内存空间,并用 0 进行预填充。
let arrBuffer = new ArrayBuffer(bytes.length)
// Uint8Array —— 将 ArrayBuffer 中的每个字节视为 0 到 255 之间的单个数字(每个字节是 8 位)。这称为 “8 位无符号整数”。
let ia = new Uint8Array(arrBuffer)
for (let i = 0; i < bytes.length; i++) {
// 更改里面的初始化内容
ia[i] = bytes.charCodeAt(i)
}
// 创建blob格式数据,并传入二进制文件和文件原本类型
let _blob = new Blob([ia], { type: mimeType })
toImg(_blob)
return _blob
}
// 利用createObjectURL转化为DataUrl格式
const toImg = function (blobObj) {
// 两种方法都可以将Blob数据转化为DataUrl格式
let imgSrc = window.URL.createObjectURL(blobObj)
//let imgSrc = window.webkitURL.createObjectURL(blobObj);
document.getElementById('blobImg').src = imgSrc
}
</script>
</html>