当前位置: 首页 > news >正文

vue-cropper实现图片裁剪

一、什么是vue-cropper?

​​Vue-Cropper​​ 是一个基于 Vue.js 的图片裁剪组件库,专为 Web 应用设计。当你在网上搜索的时候发现还有一个叫cropper的库,下面是他们的区别:

特性cropper.jsvue-cropper
框架依赖纯 JavaScript,无框架依赖专为 Vue.js 设计
包体积~200 KB (含样式)~45 KB (压缩后)
API 调用方式原生 DOM 操作Vue 组件式 API
响应式支持需手动实现原生支持 Vue 响应式
功能完整性基础裁剪+扩展插件基础裁剪+常用扩展
学习曲线较高(需熟悉原生 API)较低(Vue 开发者友好)
社区生态GitHub 32k+ StarGitHub 3.5k+ Star
移动端支持需额外配置原生优化

vue-cropper的优势:

• 纯前端实现,减轻服务器压力

• 响应式设计,完美适配移动端

• 灵活的配置选项

• 实时预览功能

• 支持多种输出格式

我正在开发的项目是基于vue3的,所以就对于vue-cropper进行讲解

二、快速上手

安装

//npm 安装
npm install vue-cropper
//yarn 安装
yarn add vue-cropper

引入

//Vue 3 组件内引入npm install vue-cropper@next
import 'vue-cropper/dist/index.css'
import { VueCropper }  from "vue-cropper";
//Vue3 全局引入import VueCropper from 'vue-cropper'; 
import 'vue-cropper/dist/index.css'const app = createApp(App)
app.use(VueCropper)
app.mount('#app')

示例代码

<template><div class="container"><input type="file" @change="handleFileChange" /><vue-cropperref="cropper":img="imageSrc":auto-crop="false":aspect-ratio="16/9"/><button @click="getResult">获取裁剪结果</button></div>
</template><script setup>
import { ref } from 'vue'const imageSrc = ref('')
const cropper = ref(null)const handleFileChange = (e) => {const file = e.target.files[0]const reader = new FileReader()reader.onload = (e) => {imageSrc.value = e.target.result}reader.readAsDataURL(file)
}const getResult = () => {cropper.value.getCropBlob(blob => {const formData = new FormData()formData.append('file', blob)// 上传逻辑...})
}
</script>

三、配置详解

基础配置项

const options = reactive({img: '',          // 图片源地址outputSize: 1,    // 输出质量(0-1)outputType: 'png',// 输出格式:png | jpeg | webpinfo: true,       // 显示裁剪信息canScale: true,   // 允许缩放autoCrop: true,   // 自动生成裁剪框fixed: false,     // 固定裁剪框尺寸fixedNumber: [4, 3], // 固定比例 [宽, 高]full: false       // 是否全屏模式
})

比例锁定实践

固定16:9的案例:

<vue-cropper:fixed="true":fixed-number="[16, 9]":img="imageSrc"@realTime="handlePreview"
/>

输出格式控制

const outputOptions = {types: ['png', 'jpeg', 'webp'],quality: {jpeg: 0.8,webp: 0.7}
}const handleExport = (type) => {cropper.value.getCropData(type, (dataURL) => {const link = document.createElement('a')link.download = `cropped.${type}`link.href = dataURLlink.click()})
}

四、案例

用户头像上传组件

<template><div class="avatar-editor"><n-uploadaccept="image/*":before-upload="handleUpload"><n-button>选择头像</n-button></n-upload><n-modal v-model:show="showCropper"><n-card style="width: 600px"><vue-cropperref="cropper":img="tempImage":fixed="true":fixed-number="[1, 1]":output-size="0.8"/><div class="action-buttons"><n-button @click="rotate(-90)">左旋转</n-button><n-button @click="rotate(90)">右旋转</n-button><n-button @click="saveAvatar">保存</n-button></div></n-card></n-modal></div>
</template><script setup>
// 完整业务逻辑
const showCropper = ref(false)
const tempImage = ref('')const handleUpload = async (file) => {const reader = new FileReader()reader.onload = (e) => {tempImage.value = e.target.resultshowCropper.value = true}reader.readAsDataURL(file)return false
}const rotate = (degree) => {cropper.value.rotate(degree)
}const saveAvatar = async () => {cropper.value.getCropBlob(async (blob) => {const formData = new FormData()formData.append('avatar', blob)try {await axios.post('/api/upload-avatar', formData)message.success('头像更新成功')showCropper.value = false} catch (error) {message.error('上传失败')}})
}
</script>

五、扩展

主题自定义

/* 自定义主题 */
.vue-cropper {--crop-border: 2px dashed #f00;--preview-bg: #f8f9fa;.crop-box {box-shadow: 0 0 10px rgba(0,0,0,0.5);}.info-item {color: #1890ff;font-size: 12px;}
}

性能优化技巧

// 压缩处理函数
const optimizeImage = (blob) => {return new Promise((resolve) => {const img = new Image()img.onload = () => {const canvas = document.createElement('canvas')const ctx = canvas.getContext('2d')canvas.width = 800canvas.height = (800 * img.height) / img.widthctx.drawImage(img, 0, 0, canvas.width, canvas.height)canvas.toBlob(resolve, 'image/webp', 0.8)}img.src = URL.createObjectURL(blob)})
}

移动端适配方案

<vue-cropper:touch="true":movable="false":zoom-on-touch="true":zoom-on-wheel="false"
/>
/* 移动端优化 */
@media (max-width: 768px) {.vue-cropper {--crop-box-width: 300px;--crop-box-height: 300px;.action-buttons {flex-direction: column;button {margin: 5px 0;}}}
}

六、常见问题

裁剪框比例不生效?

解决方案:

// 确保同时配置
fixed: true,
fixedNumber: [3, 2], 
aspectRatio: 3/2

图片显示变形?

处理方案:

const checkImage = (file) => {return new Promise((resolve) => {const img = new Image()img.onload = () => {const ratio = img.width / img.heightif (Math.abs(ratio - 3/2) > 0.1) {message.warning('建议选择3:2比例的图片')}resolve(true)}img.src = URL.createObjectURL(file)})
}

七、props

以下是全部的参数以及取值要求

名称功能默认值可选值
img裁剪图片的地址url 地址, base64, blob
outputSize裁剪生成图片的质量10.1 ~ 1
outputType裁剪生成图片的格式jpg (需传入 jpeg)jpeg, png, webp
info裁剪框的大小信息truetrue, false
canScale图片是否允许滚轮缩放truetrue, false
autoCrop是否默认生成截图框falsetrue, false
autoCropWidth默认生成截图框宽度容器的 80%0 ~ max
autoCropHeight默认生成截图框高度容器的 80%0 ~ max
fixed是否开启截图框宽高固定比例falsetrue, false
fixedNumber截图框的宽高比例(开启 fixed 生效)[1, 1][ 宽度 , 高度 ]
full是否输出原图比例的截图falsetrue, false
fixedBox固定截图框大小不允许改变true, false
canMove上传图片是否可以移动truetrue, false
canMoveBox截图框能否拖动truetrue, false
original上传图片按照原始比例渲染falsetrue, false
centerBox截图框是否被限制在图片里面falsetrue, false
high是否按照设备的 dpr 输出等比例图片truetrue, false
infoTrue展示真实输出图片宽高falsetrue, false
maxImgSize限制图片最大宽度和高度20000 ~ max
enlarge图片根据截图框输出比例倍数10 ~ max(建议不要太大)
mode图片默认渲染方式containcontain, cover, 100px, 100% auto
limitMinSize裁剪框限制最小区域10Number, Array, String
fillColor导出时背景颜色填充#ffffff, white
http://www.xdnf.cn/news/282745.html

相关文章:

  • WordPress不支持中文TAG标签出现404的解决方法
  • [python]非零基础上手之文件操作
  • JAVA:使用 MapStruct 实现高效对象映射的技术指南
  • AI功能测试源码AI聊天AI视觉AI图像AI视频AI画外音写作助手AI测试多语言无加密源码
  • 第20节:深度学习基础-反向传播算法详解
  • Linux环境下的进程创建-fork函数的使用, 进程退出exit和_exit的区别,以及进程等待waitpid和status数据的提取方法
  • 一款免费的现场大屏幕知识竞赛抢答软件
  • SpringBoot校园失物招领平台源码开发实现
  • 永磁同步电机无速度算法--基于ESO-PLL的永磁同步电机无位置传感器控制
  • 适配器模式(Adapter Pattern)
  • 内容中台的AI中枢是什么?
  • LeetCode 热题 100 48. 旋转图像
  • lombok详解
  • cline或业务系统集成n8n的工作流(MCP Server Trigger、Call n8n Workflow Tool node)
  • 【力扣刷题记录】hot100错题本(一)
  • MySQL--索引精通详解
  • QT6(33)4.6滑动组件QSlider 与QProgressBar:理论,例题的界面搭建,与功能的代码实现
  • PATHWAYS: 用于机器学习的异步分布式数据流
  • Python Cookbook-6.20 精确和安全地使用协作的超类调用
  • 【AI提示词】黑天鹅模型专家
  • 从图文到声纹:DeepSeek 多模态技术的深度解析与实战应用
  • 气泡图、桑基图的绘制
  • Sway初体验
  • 微软Phi-4-reasoning技术报告解读
  • HTML基础1-元素与页面的结构
  • “链式前向星”等三种存图方式分别输出“无向无权图”的“DFS序列”
  • ABC404E 题解
  • 2025牛客五一集训派对day4
  • 纯继电器电路控制小车自动往复运动
  • (39)VTK C++开发示例 ---选择区域