最近做了个前端图片压缩,用到了很多js文件操作api,整理一下防止健忘:
/**
* 获取文件的Base64
* @param file {File} 文件
* @param callback {Function} 回调函数,参数为获取到的base64
*/
function fileToBase64(file, callback) {
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = function () {
callback(this.result)
}
}
/**
* Base64转Blob
* @param dataURL {String} base64
* @param mimeType {String} [可选]文件类型,默认为base64中的类型
* @returns {File}
*/
function base64ToBlob(dataURL, mimeType = null) {
const arr = dataURL.split(','),
defaultMimeType = arr[0].match(/:(.*?);/)[1],
bStr = atob(arr[1]),
n = bStr.length,
u8arr = new Uint8Array(n)
let n = bStr.length
while (n--) {
u8arr[n] = bStr.charCodeAt(n)
}
return new Blob([u8arr], {type: mimeType || defaultMimeType})
}
/**
* Blob转File
* @param blob {Blob} blob
* @param fileName {String} 文件名
* @param mimeType {String} 文件类型
* @return {File}
*/
function blobToFile (blob, fileName, mimeType) {
return new File([blob], fileName, {type: mimeType})
}
/**
* Base64转File
* @param dataURL {String} base64
* @param fileName {String} 文件名
* @param mimeType {String} [可选]文件类型,默认为base64中的类型
* @returns {File}
*/
function base64ToFile(dataURL, fileName, mimeType = null) {
const arr = dataURL.split(','),
defaultMimeType = arr[0].match(/:(.*?);/)[1],
bStr = atob(arr[1]),
n = bStr.length,
u8arr = new Uint8Array(n)
let n = bStr.length
while (n--) {
u8arr[n] = bStr.charCodeAt(n)
}
return new File([u8arr], fileName, {type: mimeType || defaultMimeType})
}
/**
* 图片压缩和尺寸裁剪
* @param file {File} 图片文件
* @param quality {Number} 生成图片质量,0.0~1.0之间,质量越小、文件越小、图片越模糊
* @param callback {Function} 回调方法,参数为原文件(小于阈值的情况下)或压缩后的新文件
* @param sizeThreshold {Number} [可选]大小阈值,单位:B,默认500K
* @param targetWidth {Number} [可选]生成图片的宽度,单位:px,默认800
* @param targetHeight {Number} [可选]生成图片的高度,单位:px,默认值按宽度自适应获取
*/
function pressImg (file, quality, callback, sizeThreshold = 512000, targetWidth = 800, targetHeight = null) {
if (!file || !callback) {
console.error('pressImg参数不完整!')
return
}
if (!file.type.includes('image')) {
console.error('文件格式非图片')
return
}
fileToBase64(file, function (base64) {
if (base64) {
const image = new Image()
image.src = base64
image.onload = function () {
if (file.size <= sizeThreshold && this.width <= targetWidth) {// 大小、宽度均小于阈值,则不需处理,返回原文件
return callback(file)
}
const canvas = document.createElement('canvas')
const context = canvas.getContext('2d')
const scale = this.width / this.height
canvas.width = targetWidth
canvas.height = targetHeight || (targetWidth / scale)
context.drawImage(image, 0, 0, canvas.width, canvas.height)
const dataURL = canvas.toDataURL(file.type, quality)
const newFile = base64ToFile(dataURL, file.name)
callback(newFile)
}
}
})
}