增加图片压缩

pull/662/head
shixiaohe 2025-01-18 09:10:58 +08:00
parent 43ebd50a42
commit ca32b6d102
1 changed files with 100 additions and 21 deletions

View File

@ -71,21 +71,74 @@ type FileTypes =
//
const props = defineProps({
modelValue: propTypes.string.def(''),
drag: propTypes.bool.def(true), // ==> true
disabled: propTypes.bool.def(false), // ==> false
fileSize: propTypes.number.def(5), // ==> 5M
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // ==> ["image/jpeg", "image/png", "image/gif"]
height: propTypes.string.def('150px'), // ==> 150px
width: propTypes.string.def('150px'), // ==> 150px
borderradius: propTypes.string.def('8px'), // ==> 8px
showDelete: propTypes.bool.def(true), //
showBtnText: propTypes.bool.def(true) //
drag: propTypes.bool.def(true),
disabled: propTypes.bool.def(false),
fileSize: propTypes.number.def(5),
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']),
height: propTypes.string.def('150px'),
width: propTypes.string.def('150px'),
borderradius: propTypes.string.def('8px'),
showDelete: propTypes.bool.def(true),
showBtnText: propTypes.bool.def(true),
//
enableCompress: propTypes.bool.def(false), //
compressSize: propTypes.number.def(200), // KB
compressQuality: propTypes.number.def(0.8) // 0-1
})
const { t } = useI18n() //
const message = useMessage() //
// id
const { t } = useI18n()
const message = useMessage()
const uuid = ref('id-' + generateUUID())
//
//
const compressImage = (file: File): Promise<Blob> => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = (e) => {
const img = new Image()
img.src = e.target?.result as string
img.onload = () => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (!ctx) {
reject(new Error('Failed to get canvas context'))
return
}
//
let width = img.width
let height = img.height
const maxSize = Math.max(width, height)
if (maxSize > 1920) {
const ratio = 1920 / maxSize
width *= ratio
height *= ratio
}
canvas.width = width
canvas.height = height
ctx.drawImage(img, 0, 0, width, height)
// Blob
canvas.toBlob(
(blob) => {
if (blob) {
resolve(blob)
} else {
reject(new Error('Failed to compress image'))
}
},
file.type,
props.compressQuality
)
}
img.onerror = () => reject(new Error('Failed to load image'))
}
reader.onerror = () => reject(new Error('Failed to read file'))
})
}
const imagePreview = (imgUrl: string) => {
createImageViewer({
zIndex: 9999999,
@ -106,26 +159,52 @@ const editImg = () => {
dom && dom.dispatchEvent(new MouseEvent('click'))
}
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
const imgSize = rawFile.size / 1024 / 1024 < props.fileSize
const imgType = props.fileType
if (!imgType.includes(rawFile.type as FileTypes))
//
const beforeUpload: UploadProps['beforeUpload'] = async (rawFile) => {
//
if (!props.fileType.includes(rawFile.type as FileTypes)) {
message.notifyWarning('上传图片不符合所需的格式!')
if (!imgSize) message.notifyWarning(`上传图片大小不能超过 ${props.fileSize}M`)
return imgType.includes(rawFile.type as FileTypes) && imgSize
return false
}
//
const originalSize = rawFile.size / 1024 / 1024
if (originalSize > props.fileSize) {
message.notifyWarning(`上传图片大小不能超过 ${props.fileSize}M`)
return false
}
//
if (props.enableCompress && rawFile.size > props.compressSize * 1024) {
try {
const compressedBlob = await compressImage(rawFile)
//
if (compressedBlob.size > props.compressSize * 1024) {
message.notifyWarning(`压缩后图片仍然超过 ${props.compressSize}KB请选择更小的图片`)
return false
}
//
const newFile = new File([compressedBlob], rawFile.name, { type: rawFile.type })
return newFile
} catch (error) {
message.notifyError('图片压缩失败,请重试!')
return false
}
}
return true
}
//
const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
message.success('上传成功')
emit('update:modelValue', res.data)
}
//
const uploadError = () => {
message.notifyError('图片上传失败,请您重新上传!')
}
</script>
<style lang="scss" scoped>
.is-error {
.upload {