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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/860529.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Steam怎么卸载DLC Steam怎么只卸载DLC不卸载游戏教程

我们玩家在steam中玩游戏&#xff0c;有一个功能特别重要&#xff0c;那就是DLC&#xff0c;其实也就是一款游戏的扩展&#xff0c;很多游戏都有DLC&#xff0c;让游戏玩法特别丰富&#xff0c;比如都市天际线的DLC&#xff0c;给城市中就增加了很多建筑&#xff0c;或者更便捷…

web前端——CSS

目录 一、css概述 二、基本语法 1.行内样式表 2.内嵌样式表 3.外部样式表 4.三者对比 三、选择器 1.常用的选择器 2. 选择器优先级 3.由高到低优先级排序 四、文本,背景,列表,伪类,透明 1.文本 2.背景 3.列表 4.伪类 5.透明 五、块级,行级,行级块标签, dis…

Redis集群-计算key的插槽值等命令

文章目录 1、集群方式登录主机63792、计算key应该保存在那个插槽3、计算某个插槽中保存的key的数量4、返回指定槽中的键5、查看redis的版本5.1、Redis集群的自动故障转移5.2、主节点下线&#xff0c;从节点自动升为主节点5.2.1、杀死主节点63795.2.2、登录从机6383&#xff0c;…

AI大模型企业应用实战-Prompt让LLM理解知识

1 Prompt Prompt 可理解为指导AI模型生成特定类型、主题或格式内容的文本。 NLP中&#xff0c;Prompt 通常由一个问题或任务描述组成&#xff0c;如“给我写一篇有关RAG的文章”&#xff0c;这句话就是Prompt。 Prompt赋予LLM小样本甚至零样本学习的能力&#xff1a; LLM能力…

【网络安全学习】漏洞扫描:-03- Nikito与Wapiti漏洞扫描的使用

1️⃣ Nikto漏洞扫描 Nikto是一个开源的Web扫描评估程序&#xff0c;它可以对目标Web服务器进行快速而全面的检查&#xff0c;以发现各种潜在的安全问题和漏洞。 &#x1f170;️ 如何使用 ❓ nikto -Display 1234ep -h [域名或IP地址] -o nikto.html # -h参数&#xff1a;指…

南昌服务器托管让数据存储更安全

南昌&#xff0c;作为长江中游地区的重要中心城市&#xff0c;近年来经济发展迅速&#xff0c;产业结构不断优化。随着大数据、云计算、人工智能等新一代信息技术的快速发展&#xff0c;南昌的信息化建设步伐不断加快&#xff0c;为企业提供了良好的发展环境。在这样的背景下&a…

通过迭代器删除容器中的元素

通过之前的介绍我们知道通过迭代器来遍历单例集合的操作仍然需要借助于循环结构。而且我们知道在单例集合中调用iterator方法返回的Iterator对象中还有一个remove方法我们没有介绍&#xff0c;它的作用是删除容器中的元素。说道这里应该有人会发现一个很明显的问题&#xff0c;…

[MySql]两阶段提交

文章目录 什么是binlog使用binlog进行恢复的流程 什么是redolog缓冲池redologredolog结构 两阶段提交 什么是binlog binlog是二进制格式的文件&#xff0c;用于记录用户对数据库的修改&#xff0c;可以作用于主从复制过程中数据同步以及基于时间点的恢复&#xff08;PITR&…

Webpack: 借助 Babel+TS+ESLint 构建现代 JS 工程环境

概述 Webpack 场景下处理 JavaScript 的三种常用工具&#xff1a;Babel、TypeScript、ESLint 的历史背景、功能以及接入 Webpack 的步骤借助这些工具&#xff0c;我们能构建出更健壮、优雅的 JavaScript 应用 使用 Babel ECMAScript 6.0(简称 ES6) 版本补充了大量提升 JavaSc…

互联网应用主流框架整合之Spring Boot运维体系

先准备个简单的系统&#xff0c;配置和代码如下 # 服务器配置 server:# 服务器端口port: 8001# Spring Boot 配置 spring:# MVC 配置mvc:# Servlet 配置servlet:# Servlet 的访问路径path: /sbd# 应用程序配置application:# 应用程序名称name: SpringBootDeployment# 配置数据…

第 133 场 LeetCode 双周赛题解

A 使所有元素都可以被 3 整除的最少操作数 遍历 n u m s nums nums &#xff0c;每有一个不被 3 3 3 整除的数&#xff0c;则操作数加 1 1 1 class Solution {public:int minimumOperations(vector<int>& nums) {int res 0;for (auto x : nums)if (x % 3 ! 0)res…

杂记 | 搭建反向代理防止OpenAI API被封禁(对于此次收到邮件提示7月9日后将被屏蔽的解决参考)

文章目录 重要声明&#xff08;免责&#xff09;01 OpenAI封禁API的情况02 解决方案及原理2.1 原因分析2.2 解决方案2.3 步骤概述 03 操作步骤3.1 购买一个海外服务器3.2 申请一个域名3.3 将域名指向代理服务器3.4 在代理服务器上安装nginx3.5 配置反向代理 重要声明&#xff0…

网工内推 | 深圳网工,国企,最高20k,六险一金,NA以上认证

01 沛顿科技&#xff08;深圳&#xff09;有限公司 &#x1f537;招聘岗位&#xff1a;网络工程师 &#x1f537;岗位职责&#xff1a; 1、负责网络设备管理及维护&#xff0c;确保网络系统的稳定运行&#xff1b; 2、负责有效规划及实施网络布线系统&#xff1b; 3、负责服务…

LV、古驰奢侈品跌落神坛!2024消费风向彻底变天!2024创业新风口!2024创业小成本项目!

LV下滑6%、古驰暴跌28%&#xff0c;奢侈品在华越来越卖不动&#xff0c;外媒开始着急了&#xff01;就在前段时间&#xff0c;美媒罕见发声&#xff0c;表示今年1季度特别困难&#xff0c;有奢侈品公司在华负增长高达30%。还说如何提升销量&#xff0c;是当下奢侈品牌在华的头等…

使用matlab开发stm32总结,stm32-matlab常见的问题处理以及报错合集

1&#xff0c; 问题&#xff1a;本来是好的&#xff0c;突然编译运行报错&#xff0c;说是确少包&#xff0c; 解决方案&#xff1a;重启以后好了 2&#xff0c;有完美的马鞍波&#xff0c;为什么不能够转动呢&#xff1f; 原因是我这里模型的问题&#xff0c;我计算出来的是占…

全省高等职业学校大数据技术专业建设暨专业质量监测研讨活动顺利开展

6月21日&#xff0c;省教育评估院在四川邮电职业技术学院组织开展全省高等职业学校大数据技术专业建设暨专业质量监测研讨活动。省教育评估院副院长赖长春&#xff0c;四川邮电职业技术学院党委副书记、校长冯远洪&#xff0c;四川邮电职业技术学院党委委员、副校长程德杰等出席…

PCL笔记二 之VS环境配置(不同版本Debug+Release编译)

PCL笔记二 之VS环境配置(不同版本Debug+Release编译) PCL官网:https://github.com/PointCloudLibrary/pcl/releases众所周知,PCL是一个用于点云处理并且依赖不少三方库的一个算法库,同时在编译配置环境时也很复杂,因此这里想整理一下不同版本对应的环境配置过程,版本如下…

力扣921. 使括号有效的最少添加

Problem: 921. 使括号有效的最少添加 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 1.定义int变量res、need分别记录需要插入的左括号数和所需与左括号配对的右括号数&#xff1b; 2.遍历字符串&#xff1a; 2.1.若当为左括号&#xff0c;则need&#xff0c;表示…

[word] 如何在word中插入地图? #学习方法#其他

如何在word中插入地图&#xff1f; 人事部门在给即将入职的新员工发送入职资料时&#xff0c;为了方便新员工能快速找到公司的具体位置&#xff0c;一般都会在word资料中插入公司所在位置的地图。今天&#xff0c;小编就分享一个在word中插入地图的方法。 第一步&#xff1a;…

企智汇软件:专业项目管理系统,一体化PaaS平台!快速落地项目!

在快速变化的市场环境中&#xff0c;项目管理不再是简单的任务分配和时间跟踪&#xff0c;它更是一门需要精准决策、高效沟通和智能协作的管理工具。然而&#xff0c;面对日益复杂的项目需求、跨部门的协作挑战以及海量的信息数据&#xff0c;传统的项目管理方式往往显得力不从…