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:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
LeetCode - 199. 二叉树的右视图
题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
