介绍
在vue中使用第三方插件 image-conversion 封装的图片压缩方法
代码说明
npm install image-conversion
const imageConversion = require("image-conversion")
/**
* 压缩图片文件
* @param {File} file 原始图片文件
* @param {Object} config 压缩配置项(可选)
* @param {Number} config.size 目标大小(单位:KB)
* @param {Number} config.accuracy 压缩精度,范围 0-1(默认 0.9)
* @param {Number} config.scale 缩放比例,范围 0-10(可选,优先使用 width/height)
* @param {Number} config.width 结果图像的宽度(会自动根据图片大小生成)
* @param {Number} config.height 结果图像的高度(会自动根据图片大小生成)
* @param {Number} config.accuracy 图片质量 0-1,默认 0.92(质量越低压缩越强)
* @returns {Promise<File>} 返回压缩后的图片文件
*/
export async function compressConversion (file, config = { accuracy: 0.9, size: 300 }) {
console.log('压缩前的大小', file.size / 1024)
// 根据最大宽高设置压缩后的目标文件宽、高
const { targetWidth, targetHeight } = await getTargetFileSize(file)
config.width = targetWidth
config.height = targetHeight
console.log('config', config);
const resAvatarBlob = await imageConversion.compressAccurately(file, config)
const resAvatarFile = new window.File(
[resAvatarBlob],
file.name,
{ type: file.type },
)
console.log('压缩后的大小', resAvatarFile.size / 1024)
return resAvatarFile
}
/**
* 计算图片在最大宽高限制下的目标尺寸
* @param {File} file 图片文件
* @param {Object} config 配置项
* @param {Number} config.maxWidth 最大宽度,默认 1400
* @param {Number} config.maxHeight 最大高度,默认 1400
* @returns {Promise<{ targetWidth: number, targetHeight: number }>}
*/
// 获取压缩后的图片尺寸
function getTargetFileSize (file, config = { maxWidth: 1400, maxHeight: 1400 }) {
return new Promise(resolve => {
const { maxWidth, maxHeight } = config
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
let img = new Image();
img.src = reader.result;
img.onload = () => {
let targetWidth = img.width
let targetHeight = img.height
let originWidth = img.width
let originHeight = img.height
// 图片尺寸超过的限制
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// 更宽,按照宽度限定尺寸
targetWidth = maxWidth
targetHeight = Math.round(maxWidth * (originHeight / originWidth))
} else {
targetHeight = maxHeight
targetWidth = Math.round(maxHeight * (originWidth / originHeight))
}
}
resolve({ targetWidth, targetHeight })
}
}
})
}
使用案例
<template>
<el-upload
class="upload-demo"
action="" <!-- 实际开发中配置上传地址 -->
:http-request="handleUpload"
:show-file-list="false"
accept="image/*"
>
<el-button type="primary">上传图片</el-button>
</el-upload>
</template>
<script setup>
import { compressConversion } from '@/utils/compressConversion' // 路径按实际修改
import { ElMessage } from 'element-plus'
const handleUpload = async ({ file }) => {
try {
const compressedFile = await compressConversion(file, { accuracy: 0.9, size: 300 })
// 示例上传请求
const formData = new FormData()
formData.append('file', compressedFile)
// 替换为你的上传接口
const res = await fetch('/api/upload', {
method: 'POST',
body: formData
})
if (!res.ok) throw new Error('上传失败')
ElMessage.success('上传成功')
} catch (err) {
console.error(err)
ElMessage.error('上传失败')
}
}
</script>