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

vue中实现图片裁剪

在现代Web应用中,图片处理是一个常见的需求。本文将介绍如何使用Vue.js结合Cropper.js实现一个简单的图片裁剪功能。以下是实现该功能的完整代码。

代码实现

<template><div class="c-copper-container" :class="{'wd260' : type == 'articlesubmit'}"><div class="c-copper-box"><div class="c-image-box"><img :src="copperImgUrl" id="image" alt="暂无图片"></div><div class="c-preview-box"><div class="img-preview"><div class="title">预览</div><div class="preview"><img :src="copperImgUrl" alt="暂无图片"></div></div><div class="img-upload-btn"><el-button icon="cs-format-image" size="mini" plain>上传图片</el-button><input type="file" accept="image/png,image/jpeg,image/jpg" id="imgFile" @change="getFile"></div></div></div><div class="c-btn-group"><el-button type="info" plain @click="cancel">取消</el-button><el-button type="primary" @click="getCropperImg">确定</el-button></div></div>
</template>
代码解析
  1. <div class="c-copper-container" :class="{'wd260' : type == 'articlesubmit'}">

    • 定义了一个容器,并根据 type 属性动态添加 wd260 类。
  2. <div class="c-copper-box">

    • 包含图片裁剪和预览的主要布局。
  3. <div class="c-image-box">

    • 裁剪图片显示区域。
  4. <img :src="copperImgUrl" id="image" alt="暂无图片">

    • 绑定了一个图片标签,用于显示裁剪的图片。
  5. <div class="c-preview-box">

    • 图片预览区域。
  6. <div class="img-preview">

    • 包含预览标题和预览图片。
  7. <el-button icon="cs-format-image" size="mini" plain>上传图片</el-button>

    • 上传图片按钮。
  8. <input type="file" accept="image/png,image/jpeg,image/jpg" id="imgFile" @change="getFile">

    • 文件输入框,监听文件变化事件 getFile
  9. <el-button type="info" plain @click="cancel">取消</el-button>

    • 取消按钮,触发 cancel 方法。
  10. <el-button type="primary" @click="getCropperImg">确定</el-button>

    • 确定按钮,触发 getCropperImg 方法。

JavaScript 部分

<script>import { dataURItoBlob } from '@/utils'export default {name: 'CropperImage',data () {return {copperImgUrl: '', // 被剪裁的图片地址option: {viewMode: 1, // 裁剪框只能图片内部移动dragMode: 'move', // 裁剪框只可以移动,不可以新建aspectRatio: 1, // 裁剪框比例preview: '.preview', // 预览的dom节点checkCrossOrigin: false, // 不检查跨域图像movable: false, // 设置图片可不移动rotatable: false, // 设置图片不可旋转scalable: false, // 设置图片不可缩放zoomable: false, // 设置图片不可放大zoomOnTouch: false, // 设置图片不可被拖动触摸放大toggleDragModeOnDblclick: true, // 点击两次时可以在“crop”和“move”之间切换拖拽模式minCropBoxWidth: '5', // 裁剪层最小宽度minCropBoxHeight: '5' // 裁剪层最小高度}}},props: {cropperOption: {type: Object,default: () => {return null}},fileSize: {type: Number,default: 0.8},fileType: {type: String,default: 'jpeg'},imageFile: {},sizeNum:{type: Number,default: 0},type:{type: String,default: ''}},watch: {imageFile (file) {this.fileHandle(file)}},methods: {initCropperModel () {if (this.cropperOption) {for (let key in this.option) {this.option[key] = this.cropperOption[key] || this.option[key]}}let $image = document.getElementById('image')this.cropper = new Cropper($image, this.option)},getFile (e) {let file = e.target.files[0]let _sizeNum = this.sizeNumif(_sizeNum){const isLtSize = file.size / 1024 / 1024 < _sizeNumif (!isLtSize) {this.$message({message: this.type == 'articlesubmit' ? `图片大小不能超过 ${_sizeNum}M!` :  `图片大小不能超过 ${_sizeNum * 1000}kb!`,type: 'error'})e.target.value = ''return false}}this.fileHandle(file)},fileHandle (file) {if (!file) return if (!window.FileReader) return let vm = thislet reader = new FileReader()reader.readAsDataURL(file)reader.onloadend = function () {vm.copperImgUrl = this.resultvm.resetCropperImg()}},resetCropperImg () {this.cropper.reset()this.cropper.replace(this.copperImgUrl)},getCropperImg () {let canvas = this.cropper.getCroppedCanvas();if (this.fileType === 'image/png') {let ctx = canvas.getContext('2d');ctx.fillStyle = "rgba(0,0,0,0)"; ctx.fillRect(0, 0, canvas.width, canvas.height);}let newImageData = canvas.toDataURL('image/png');let blob = dataURItoBlob(newImageData);let formData = new FormData();formData.append('icon', blob);this.$emit('cropped', newImageData, formData);},cancel () {this.$emit('cancel')}},created () {this.fileHandle(this.imageFile)},mounted () {this.initCropperModel()},beforeDestroy () {this.copperImgUrl = ''this.cropper.destroy()}}
</script>
代码解析
  1. data ():

    • 定义组件的数据属性,包括图片URL和裁剪器的配置项。
  2. props:

    • 定义父组件传入的属性,包括裁剪配置、文件大小和类型等。
  3. watch:

    • 监听 imageFile 的变化,当文件变化时调用 fileHandle 方法。
  4. methods:

    • initCropperModel ():初始化 Cropper.js 实例。
    • getFile (e):获取上传的文件并处理。
    • fileHandle (file):处理上传的文件,将文件转换为Base64格式。
    • resetCropperImg ():重置裁剪器的图片。
    • getCropperImg ():获取裁剪后的图片,并将其转换为Blob格式。
    • cancel ():取消操作。
  5. created ()

    • 在组件创建时处理初始图片文件。
  6. mounted ()

    • 在组件挂载时初始化裁剪器。
  7. beforeDestroy ()

    • 在组件销毁前清理裁剪器实例。

样式部分

<style scoped lang="stylus" rel="stylesheet">.c-copper-container {width 450pxfont-size 12pxmargin-top 20px&.wd260{width 260px.img-upload-btn .el-button{padding 7px 5px}.c-image-box {width 188pxheight 188px& img {max-width 100%}>>> .cropper-bg{width 200px !important}}.c-preview-box {width 80px.img-preview {padding 5px 8pxheight 100px}.preview {width 60pxheight 60px}}}.c-copper-box {display flex}.c-image-box {width 250pxheight 250pxmargin-right 20pxbackground #868686& img {max-width 100%}}.c-preview-box {width 180pxtext-align center.img-preview {width 100%padding 10px 15pxheight 200pxbox-sizing border-boxborder 1px solid #e8e8e8background #fafafa}.title {padding-bottom 5px}.preview {width 148pxheight 148pxoverflow hiddenbackground-color #fffborder 1px solid #e8e8e8display inline-block}}.img-upload-btn {position relativemargin-top 18px&:hover .el-button {color #168FCAborder-color #168FCAtransition all .1s}& /deep/ i, & /deep/ span {display inline-blockvertical-align middle}.el-button {width 100%border-radius 0}#imgFile {position absolutewidth 100%height 100%top 0left 0opacity 0cursor pointer}}.c-btn-group {padding-top 20pxtext-align center.el-button {width 100px}}}
</style>
代码解析
  1. 定义了组件的样式,包括容器宽度、字体大小等。

  2. 使用了 scoped 属性,确保样式仅应用于当前组件。

  3. 采用了Stylus语法编写样式,提高了代码的可读性和易维护性。

总结

通过以上代码,我们实现了一个基于Vue.js和Cropper.js的图片裁剪组件,用户可以上传图片并进行裁剪操作,最终获取裁剪后的图片数据。这个组件可以方便地集成到Vue.js应用中,为用户提供了良好的图片处理体验。


http://www.mrgr.cn/news/9904.html

相关文章:

  • 【PDFBox 缺失类库异常解决】
  • 【R语言】基于多模型的变量重要性图 (Variable Importance Plots)
  • 计算循环冗余码(CRC)--软考笔记
  • 算法-生命游戏(289矩阵)
  • 浮点运算的硬件加速
  • 电压增益、功率增益及其之间的联系
  • 基于Springboot + vue + mysql 车辆充电桩管理系统 设计实现
  • Ubuntu 22.04上稳定安装与配置搜狗输入法详细教程
  • 【Linux 从基础到进阶】NFS与Samba文件共享配置
  • 学习笔记七:基于Jenkins+k8s+Git+DockerHub等技术链构建企业级DevOps容器云平台
  • C#网络请求封装,HttpClient 静态单实例
  • 浅谈Java SpringBoot和Spring区别
  • 2024 年顶级 Flutter UI 框架和库
  • 垂直电商的未来发展方向与开源 AI 智能名片 O2O 小程序的融合
  • 如何借助BI高效打造经营分析看板?从业七年的数据分析师给出这四点建议!
  • SpringBoot的异常java.lang.ClassNotFoundException: io.r2dbc.spi.ValidationDepth
  • Cesium 视频投射
  • NFT Insider #144:Sandbox 投资 9 万美元助力区块链活动
  • Ollama 使用指南:Linux、Windows 和 macOS
  • 2001-2023年上市公司数字化转型年报词频统计(吴非、赵宸宇、甄红线等300+个关键词)