cropperjs 裁剪/框选图片
1.效果

2.使用组件
<!-- 父级 --><Cropper ref="cropperRef" :imgUrl="url" @searchImg="searchImg"></Cropper>
3.封装组件
<template><el-dialog :title="title" :visible.sync="dialogVisible" width="1000px"><input ref="input" type="file" name="image" @change="setImage" /><div class="flex justify-around"><div class="w-480px h-270px flex justify-center items-center"><divv-show="!imgSrc"@click="showFileChooser"class="w-full h-full flex cursor-pointer justify-center items-center border-1px border-dashed border-gray-300 rounded-lg"><i class="font-size-20px el-icon-plus avatar-uploader-icon"></i></div><!-- :aspect-ratio="16 / 16" --><vue-cropperv-show="imgSrc"class="w-full h-full"ref="cropper":src="imgSrc"alt="Source Image"@ready="ready"@cropstart="cropstart"@cropmove="cropmove"@cropend="cropend"@crop="crop"@zoom="zoom"preview=".preview":autoCropArea="autoCropArea"></vue-cropper></div><div class="w-420px"><div class="font-bold color-#666 ml-20px mb-10px">预览</div><div v-show="!imgSrc" class="preview_empty ml-20px"></div><div v-show="imgSrc" class="preview ml-20px"></div><!-- <div>裁剪图片</div><div class="cropped-image"><el-image class="h-180px" v-if="cropImg" :src="cropImg" alt="Cropped Image" /><div v-else class="crop-placeholder" /></div> --><div class="actions mt-10px ml-10px"><el-button class="mb-10px ml-10px" type="primary" @click="zoom(0.2)" size="small">放大</el-button><el-button class="mb-10px" type="primary" @click="zoom(-0.2)" size="small">缩小</el-button><el-button class="mb-10px" type="primary" @click="move(-10, 0)" size="small">左移</el-button><el-button class="mb-10px" type="primary" @click="move(10, 0)" size="small">右移</el-button><el-button class="mb-10px" type="primary" @click="move(0, -10)" size="small">上移</el-button><el-button class="mb-10px" type="primary" @click="move(0, 10)" size="small">下移</el-button><el-button class="mb-10px" type="primary" @click="rotate(90)" size="small">旋转90°</el-button><el-button class="mb-10px" type="primary" @click="rotate(-90)" size="small">旋转-90°</el-button><!-- <el-button class="mb-10px" type="primary" @click="flipX" size="small">水平翻转</el-button><el-button class="mb-10px" type="primary" @click="flipY" size="small">垂直翻转</el-button> --><!-- <el-button class="mb-10px" type="success" @click="cropImage" size="small">搜索</el-button> --><el-button class="mb-10px" type="primary" @click="reset" size="small" plain>重置</el-button><el-buttonv-if="!isHideFileChooser"class="mb-10px"type="success"@click="showFileChooser"size="small"plain>更换图片</el-button><!-- <el-button class="mb-10px" type="primary" @click="getCropBoxData" size="small">获取裁剪框数据</el-button><el-button class="mb-10px" type="primary" @click="setCropBoxData" size="small">设置裁剪框数据</el-button><el-button class="mb-10px" type="primary" @click="getData" size="small">获取裁剪数据</el-button><el-button class="mb-10px" type="primary" @click="setData" size="small">设置裁剪数据</el-button> --></div></div></div><span slot="footer" class="dialog-footer"><el-button size="small" @click="dialogVisible = false">取 消</el-button><el-button size="small" type="primary" @click="cropImage">搜索</el-button></span></el-dialog>
</template><script>
import VueCropper from 'vue-cropperjs'
import 'cropperjs/dist/cropper.css'export default {name: 'Cropper',components: { VueCropper },props: {title: {type: String,default: '图片框选'},imgUrl: {type: String,default: ''},autoCropArea: {type: Number,default: 0.6},isHideFileChooser: {type: Boolean,default: true}},data() {return {imgSrc: '',dialogVisible: false,cropImg: ''}},watch: {imgUrl(val) {if (val) {this.imgSrc = valconsole.log('🚀 ~ imgUrl ~ this.imgSrc:', this.imgSrc)}}},methods: {open() {if (!this.imgUrl) {this.imgSrc = ''}this.dialogVisible = true},handleClose() {this.$emit('close')},ready() {// console.log('🚀 ~ ready ~ this.$refs.cropper:', this.$refs.cropper)},cropImage() {// get image data for post processing, e.g. upload or setting image srcthis.cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL()const base64Data = this.cropImg.split(',')[1]this.$emit('searchImg', base64Data)this.dialogVisible = false},cropstart() {// console.log('🚀 ~ cropstart ~')},cropmove() {// console.log('🚀 ~ cropmove ~')},cropend() {// console.log('🚀 ~ cropend ~')},crop(data) {// console.log('🚀 ~ crop ~ data:', data)},flipX() {const dom = this.$refs.flipXlet scale = dom.getAttribute('data-scale')scale = scale ? -scale : -1this.$refs.cropper.scaleX(scale)dom.setAttribute('data-scale', scale)},flipY() {const dom = this.$refs.flipYlet scale = dom.getAttribute('data-scale')scale = scale ? -scale : -1this.$refs.cropper.scaleY(scale)dom.setAttribute('data-scale', scale)},getCropBoxData() {this.data = JSON.stringify(this.$refs.cropper.getCropBoxData(), null, 4)},getData() {this.data = JSON.stringify(this.$refs.cropper.getData(), null, 4)console.log('🚀 ~ getData ~ this.data:', this.data)},move(offsetX, offsetY) {this.$refs.cropper.move(offsetX, offsetY)},reset() {this.$refs.cropper.reset()},rotate(deg) {this.$refs.cropper.rotate(deg)},setCropBoxData() {if (!this.data) returnthis.$refs.cropper.setCropBoxData(JSON.parse(this.data))},setData() {if (!this.data) returnthis.$refs.cropper.setData(JSON.parse(this.data))},setImage(e) {const file = e.target.files[0]if (file.type.indexOf('image/') === -1) {alert('Please select an image file')return}if (typeof FileReader === 'function') {const reader = new FileReader()reader.onload = (event) => {this.imgSrc = event.target.result// rebuild cropperjs with the updated sourcethis.$refs.cropper.replace(event.target.result)}reader.readAsDataURL(file)} else {alert('Sorry, FileReader API not supported')}},showFileChooser() {this.$refs.input.click()},zoom(percent) {this.$refs.cropper.relativeZoom(percent)}},mounted() {this.imgSrc = this.imgUrl}
}
</script><style lang="scss" scoped>
input[type='file'] {display: none;
}.preview-area {width: 100%;
}.preview-area p {font-size: 1.25rem;margin: 0;margin-bottom: 1rem;
}.preview-area p:last-of-type {margin-top: 1rem;
}.preview {width: 270px;height: calc(270px * (9 / 16));overflow: hidden;background-color: #f5f5f5;
}.preview_empty {width: 270px;height: calc(270px * (9 / 16));overflow: hidden;background-color: #f5f5f5;
}
.crop-placeholder {width: 100%;height: 200px;background: #ccc;
}.cropped-image img {max-width: 100%;
}
</style>相关文章:
cropperjs 裁剪/框选图片
1.效果 2.使用组件 <!-- 父级 --><Cropper ref"cropperRef" :imgUrl"url" searchImg"searchImg"></Cropper>3.封装组件 <template><el-dialog :title"title" :visible.sync"dialogVisible" wi…...
ArkTS开发系列之事件(2.8.2手势事件)
上篇回顾:ArkTS开发系列之事件(2.8.1触屏、键鼠、焦点事件) 本篇内容:ArkTS开发系列之事件(2.8.2手势事件) 一、绑定手势方法 1. 常规手势绑定方法 Text(手势).fontSize(44).gesture(TapGesture().onAct…...
【MATLAB源码-第135期】基于matlab的变色龙群优化算法CSA)机器人栅格路径规划,输出做短路径图和适应度曲线。
操作环境: MATLAB 2022a 1、算法描述 变色龙群优化算法(Chameleon Swarm Algorithm,CSA)是一种新颖的群体智能优化算法,受到自然界中变色龙捕食和社交行为的启发。变色龙以其独特的适应能力而著称,能够根…...
使用Python实现深度学习模型:语言模型与文本生成
语言模型是自然语言处理中的核心任务之一,它们用于预测文本中的下一个单词或生成与输入文本相关的新文本。本文将详细介绍如何使用Python实现一个语言模型,并通过这个模型进行文本生成。 我们将使用TensorFlow和Hugging Face的Transformers库来实现这一任务。 1. 语言模型简…...
大数据面试题之Hive(3)
目录 Hive的函数:UDF、UDAF、UDTF的区别? UDF是怎么在Hive里执行的 row_number,rank,dense_rank的区别 Hive count(distinct)有几个reduce,海量数据会有什么问题 HQL:行转列、列转行 一条HQL从代码到执行的过程 了解Hive S…...
华为OD机考题HJ17 坐标移动
前言 应广大同学要求,开始以OD机考题作为练习题,看看算法和数据结构掌握情况。有需要练习的可以关注下。 描述 开发一个坐标计算工具, A表示向左移动,D表示向右移动,W表示向上移动,S表示向下移动。从&am…...
redis修改密码
在Redis中,修改密码通常涉及编辑Redis配置文件或者在运行时通过Redis命令动态修改。 温馨提示:(运行时直接参考第2条) 1.编辑配置文件: 找到Redis配置文件redis.conf,通常位于/etc/redis/或/usr/local/e…...
《昇思 25 天学习打卡营第 7 天 | 模型训练 》
《昇思 25 天学习打卡营第 7 天 | 模型训练 》 活动地址:https://xihe.mindspore.cn/events/mindspore-training-camp 签名:Sam9029 模型训练 本章节-结合前几张的内容所讲-算是一节综合实践 mindscope 框架使用张量 数据类型数据集下载与加载网络构建函…...
HTML/CSS 基础
1、<input type"checkbox" checked> checked 默认选中为复选框 2、表格中的标题<caption> 3、文字标签直接加 title 4、<dl>为自定义列表的整体,包裹<dt><dd> <dt>自定义列表的主题 <dd>主题的每一项内容 5、…...
Linux系统安装Lua语言及Lua外部库
安装Lua Lua语言是一种轻量级、高效且可扩展的脚本语言,具有简洁易学的语法和占用资源少的特点。它支持动态类型,提供了丰富的表达式和运算符,同时具备自动垃圾回收机制和跨平台性。Lua语言易于嵌入到其他应用程序中,并可与其他语…...
前端技术栈学习:Vue2、Vue cli脚手架、ElementUI组件库、Axios
1 基本介绍 (1)Vue 是一个前端框架, 易于构建用户界面 (2)Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或项目整合 (3)支持和其它类库结合使用 (4&#…...
pycharm中取消Typo:In word ‘xxx‘提示(绿色波浪线提示)的方法
#事故现场 使用pycharm写python代码出现绿色波浪线的提示,并提示Typo:In word ‘xxx’,这是pycharm检测到单词拼写错误、不规范; 那如何取消这种提示呢? #解决方法 方法一:Settings → Editor → Inspections → P…...
js中的浅拷贝和深拷贝
浅拷贝Shallow Copy 浅拷贝只复制对象的顶层属性及其引用,而不复制这些引用所指向的对象。如果原始对象中的某个属性是一个对象或数组,那么浅拷贝后的对象将包含对这个内部对象或数组的引用,而不是这个对象或数组的一个新副本。 let obj1 …...
【Linux】常用基本命令
wget网址用于直接从网上下载某个文件到服务器,当然也可以直接从网上先把东西下到本地然后用filezilla这个软件来传输到服务器上。 当遇到不会的命令时候,可以使用man “不会的命令”来查看这个命令的详细信息。比如我想要看看ls这个命令的详细用法&…...
uniapp——上传图片获取到file对象而非临时地址——基础积累
最近在看uniapp的代码,遇到一个需求,就是要实现上传图片的功能 uniapp 官网地址:https://uniapp.dcloud.net.cn/ 上传图片有对应的API: uni.chooseImage方法:https://uniapp.dcloud.net.cn/api/media/image.html#choo…...
vue3 antdv RadioButton默认值选择问题处理
1、先上官方文档: Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js 官方代码: <template><div><div><a-radio-group v-model:value"value1"><a-radio-button value"a…...
最佳实践,一款基于 Flutter 的桌面应用
前言 这篇文章介绍作为一名后端开发人员,快速的入门前端或者客户端一些相关的技术的心得。先来说说为什么作为一名后端开发人员也需要学习一些前端或者客户端相关的技术。通常来说,深耕一个领域没有错,因为社会常常就是这样分工的࿰…...
python第一个多进程爬虫
使用 multiprocessing 模块实现多进程爬取股票网址买卖数据的基本思路是: 定义爬虫函数,用于从一个或多个股票网址上抓取数据。创建多个进程,每个进程执行爬虫函数,可能针对不同的股票或不同的网页。使用 multiprocessing.Queue …...
在Ubuntu 18.04上安装和配置Ansible的方法
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 配置管理系统旨在简化对大量服务器的控制,适用于管理员和运维团队。它们允许您从一个中央位置以自动化的方式控制许多…...
【详细教程】如何使用YOLOv10进行图片与视频的目标检测
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
XCTF-web-easyupload
试了试php,php7,pht,phtml等,都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接,得到flag...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
