使用 element-ui 和 vue-cropper 實現圖片上傳按尺寸大小裁剪功能,這是 github源碼
element-ui upload 組件
-
element-ui
upload
組件上傳圖片,設置自動上傳,使用before-upload
鉤子進行上傳校驗 -
將圖片文件轉化爲圖片路徑進行裁剪
<el-upload
class="upload-banner"
drag
action=""
:auto-upload="true"
:on-change="handleCrop"
:before-upload="beforeAvatarUpload"
:show-file-list="false"
>
<el-image v-if="cropperData.iconUrl" :src="cropperData.iconUrl" fit="contain" class="avatar"></el-image>
<div v-else class="upload-box">
<el-button type="primary" class="select-btn">選擇圖片</el-button>
</div>
</el-upload>
<script>
handleCrop (file) {
// 點擊彈出剪裁框
this.$nextTick(() => {
if (this.canCropper) {
this.cropperOption.img = window.URL.createObjectURL(file.raw) // 將圖片轉化爲路徑
this.showCropper = this.canCropper
}
})
},
beforeAvatarUpload (file) {
// 上傳前校驗
const isJPG = file.type === 'image/jpeg' || file.type === 'image/jpg' || file.type === 'image/png'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error('上傳頭像圖片只能是 JPG/PNG 格式!')
}
if (!isLt2M) {
this.$message.error('上傳頭像圖片大小不能超過 2 MB!')
}
// 校驗通過後顯示裁剪框
this.canCropper = isJPG && isLt2M
return false
}
</script>
vue-cropper
-
將圖片縮放到設定的尺寸
-
重新上傳圖片時,需重新將圖片轉化爲圖片路徑
-
將
base64
轉化爲圖片文件
<el-dialog
title="圖片裁切"
class="cropper-dialog"
:close-on-click-modal="false"
:visible="dialogVisible"
center
@close="close"
>
<div class="cropper-wrap">
<div
class="cropper-box"
:style="cropperStyle"
>
<vue-cropper
ref="cropper"
:img="option.img"
:output-size="option.size"
:output-type="option.outputType"
:info="option.info"
:full="option.full"
:canScale="option.canScale"
:can-move="option.canMove"
:can-move-box="option.canMoveBox"
:fixed="option.fixed"
:fixed-box="option.fixedBox"
:original="option.original"
:auto-crop="option.autoCrop"
:auto-crop-width="option.autoCropWidth"
:auto-crop-height="option.autoCropHeight"
:center-box="option.centerBox"
:high="option.high"
:info-true="option.infoTrue"
:max-img-size="option.maxImageSize"
:enlarge="option.enlarge"
:mode="option.mode"
:maxImgSize="option.maxImgSize"
@realTime="realTime"
/>
</div>
<div class="preview-box">
<div class="preview-title">
<span>預覽</span>
<span @click="upload" class="preveiw-upload">重新上傳</span>
</div>
<input
ref="upload"
type="file"
style="position:absolute; clip:rect(0 0 0 0);"
accept="image/png, image/jpeg, image/jpg"
@change="uploadImg"
>
<div
:style="previewStyle"
class="preview-img"
>
<div :style="preview.div">
<img
:style="preview.img"
:src="preview.url"
/>
</div>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="finish" :loading="loading">確認</el-button>
</div>
</el-dialog>
// 裁剪組件的基礎配置option
option: {
img: '', // 裁剪圖片的地址
outputSize: 1, // 裁剪生成圖片的質量
outputType: 'png', // 裁剪生成圖片的格式
full: true, // 是否輸出原圖比例的截圖
info: true, // 圖片大小信息
canScale: true, // 圖片是否允許滾輪縮放
autoCrop: true, // 是否默認生成截圖框
autoCropWidth: 200, // 默認生成截圖框寬度
autoCropHeight: 150, // 默認生成截圖框高度
canMove: true, // 上傳圖片是否可以移動
fixedBox: true, // 固定截圖框大小 不允許改變
fixed: false, // 是否開啓截圖框寬高固定比例
canMoveBox: true, // 截圖框能否拖動
original: false, // 上傳圖片按照原始比例渲染
centerBox: false, // 截圖框是否被限制在圖片裏面
height: true,
infoTrue: false, // true 爲展示真實輸出圖片寬高 false 展示看到的截圖框寬高
enlarge: 1, // 圖片根據截圖框輸出比例倍數
mode: 'container', // 圖片默認渲染方式
maxImgSize: 375 // 限制圖片最大寬度和高度
}
將 base64 圖片轉化爲圖片文件
由於後臺只能識別 jpg
、png
圖片格式,需要將 base64
圖片轉化爲圖片文件
// 將base64轉換爲文件
dataURLtoFile (dataurl, filename) {
let arr = dataurl.split(',')
let mime = arr[0].match(/:(.*?);/)[1]
let bstr = atob(arr[1])
let len = bstr.length
let u8arr = new Uint8Array(len)
while (len--) {
u8arr[len] = bstr.charCodeAt(len)
}
return new File([u8arr], filename, { type: mime })
}
vue-cropper 相關配置
Attribute
參數 | 說明 | 類型 | 可選值 |
---|---|---|---|
img | 裁剪圖片的地址 | String / Blob | — |
outputSize | 裁剪生成圖片的質量 | Number | 0.1 - 1 |
outputType | 裁剪生成圖片的格式 | String | jpeg / png / webp |
info | 裁剪框的大小信息 | Boolean | — |
canScale | 圖片是否允許滾輪縮放 | Boolean | — |
autoCrop | 是否默認生成截圖框 | Boolean | — |
autoCropWidth | 默認生成截圖框寬度 | Number | 0~max |
autoCropHeight | 默認生成截圖框高度 | Number | 0~max |
fixed | 是否開啓截圖框寬高固定比例 | Boolean | — |
fixedNumber | 截圖框的寬高比例 | Array | — |
full | 是否輸出原圖比例的截圖 | Boolean | — |
fixedBox | 固定截圖框大小 不允許改變 | Boolean | — |
canMove | 上傳圖片是否可以移動 | Boolean | — |
canMoveBox | 截圖框能否拖動 | Boolean | — |
original | 上傳圖片按照原始比例渲染 | Boolean | — |
centerBox | 截圖框是否被限制在圖片裏面 | Boolean | — |
high | 是否按照設備的 dpr 輸出等比例圖片 | Boolean | — |
infoTrue | true 爲展示真實輸出圖片寬高 false 展示看到的截圖框寬高 | Boolean | — |
maxImgSize | 限制圖片最大寬度和高度 | Number | 0~max |
enlarge | 圖片根據截圖框輸出比例倍數 | Number | 0-max |
mode | 圖片默認渲染方式 | String | contain , cover, 100px, 100% auto |
Events
事件名 | 說明 | 參數 |
---|---|---|
imgMoving | 圖片移動回調函數 | data |
cropMoving | 截圖框移動回調函數 | data |
imgLoad | 圖片加載回調函數 | message |
realTime | 實時預覽回調函數 | data |
Methods
方法名 | 說明 | 參數 |
---|---|---|
startCrop | 開始截圖 | — |
stopCrop | 停止截圖 | — |
clearCrop | 清除截圖 | — |
changeScale | 修改圖片大小 正數爲變大 負數變小 | — |
getImgAxis | 獲取圖片基於容器的座標點 | — |
getCropAxis | 獲取截圖框基於容器的座標點 | — |
goAutoCrop | 自動生成截圖框函數 | — |
rotateRight | 向右邊旋轉 90 度 | — |
rotateLeft | 向左邊旋轉 90 度 | — |
cropW | 截圖框寬度 | — |
cropH | 截圖框高度 | — |
getCropData | 獲取截圖的 base64 數據 | data |
getCropBlob | 獲取截圖的 blob 數據 | data |