图片裁切以及图片预览的过程

图片裁切以及图片预览的过程:

1.图片裁切功能crop:(样式/更新)

网站:https://github.com/fengyuanchen/cropperjs
预览功能网站:https://fengyuanchen.github.io/cropperjs/

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jcMYMTf6-1617323387035)(D:\项目笔记\732c9beeea86b44a9b7ed777a023d60.png)]

这个包是原生的js语言写的,可以用到各种语言中,包括vue,jquery,react都可以的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ssuTezQi-1617323387040)(D:\项目笔记\fab9e4a479abfae73ae6f5d5f9a5979.png)]

使用步骤:

(1)打开终端,进行安装

npm install cropperjs

(2)example解释

  1. Wrap the image or canvas element with a block element (container):意思是将图片或者是 canvas element(canvas元素)放到块级元素中
<!-- Wrap the image or canvas element with a block element (container) -->
<div>
  <img id="image" src="picture.jpg">
</div>
代码演示:这是咱们预览图片的代码

但是要将其放到盒子中

<img width="150" :src="previewImage" alt="">
<div>
  <img width="150" :src="previewImage" alt="">
</div>
2.Ensure the size of the image fit the container perfectly:确保图片的大小填充到容器中

给img设置一个样式,必须按照要求来

/* Ensure the size of the image fit the container perfectly */
img {
  display: block;

  /* This rule is very important, please don't ignore this */
  max-width: 100%;
}

正确代码显示:

<div class="preview-image-wrap">
   <img class="preview-image" :src="previewImage" alt="">
</div>

<style>
  .preview-image-wrap .preview-image {
    display: block;
    max-width: 100%;
  }
</style>

**效果显示:**图片完全填充上去了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CEK8l0li-1617323387044)(D:\项目笔记\109d09eb28bd26eb25af176512b478f.png)]

(3)将下面两行代码引入到需要使用的页面

import 'cropperjs/dist/cropper.css';
import Cropper from 'cropperjs';

(4)初始化页面,还是复制代码

const image = document.getElementById('image');
const cropper = new Cropper(image, {
  aspectRatio: 16 / 9,
  crop(event) {
    console.log(event.detail.x);
    console.log(event.detail.y);
    console.log(event.detail.width);
    console.log(event.detail.height);
    console.log(event.detail.rotate);
    console.log(event.detail.scaleX);
    console.log(event.detail.scaleY);
  }
})

注意点:

(1)const image = document.getElementById(‘image’)这是获取图片的DOM节点,但是在vue中是通过ref来获取的,所以这里需要进行一下更改
const image = this.$refs['preview-image']
(2)下一步是初始化裁切器new了一个cropper,并把获取的DON当成参数给传了进去,这一步的作用是初始化裁切器
 const cropper = new Cropper(image, {
        aspectRatio: 16 / 9,
        crop (event) {
          console.log(event.detail.x)
          console.log(event.detail.y)
          console.log(event.detail.width)
          console.log(event.detail.height)
          console.log(event.detail.rotate)
          console.log(event.detail.scaleX)
          console.log(event.detail.scaleY)
        }
      })
(3)这串代码的位置:这串代码是等图片预览加载完之后才会起作用,这个就有讲究了
在和dialog配合使用的时候,dialog有个钩子函数opened
<el-dialog
    title="提示"
    :visible.sync="dialogVisible"
    width="30%" :append-to-body="true" @opened="onDialogOpened">
      <div class="preview-image-wrap">
        <img class="preview-image" :src="previewImage" alt="" ref="preview-image">
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
methods: {
    onDialogOpened () {
      // const image = document.getElementById('image')这是获取图片的DOM节点,但是在vue中是通过ref来获取的,所以这里需要进行一下更改
      const image = this.$refs['preview-image']
      // 下一步是初始化裁切器new了一个cropper,并把获取的DON当成参数给传了进去,这一步的作用是初始化裁切器
      const cropper = new Cropper(image, {
        aspectRatio: 16 / 9,
        crop (event) {
          console.log(event.detail.x)
          console.log(event.detail.y)
          console.log(event.detail.width)
          console.log(event.detail.height)
          console.log(event.detail.rotate)
          console.log(event.detail.scaleX)
          console.log(event.detail.scaleY)
        }
      })
    }
  }
}

做到这一步出现一个问题:

就是预览的图片必须刷新一下,才可以选别的图片,接下来就是如何解决这个问题,原因是这个裁切器没有去更新

解决方法:

(1)裁切器.replace方法

首先进行一次判断

if (this.cropper) {
        // replace
        this.cropper.replace(this.previewImage)
        return
      }
onDialogOpened () {
      if (this.cropper) {
        // replace
        this.cropper.replace(this.previewImage)
        return
      }
      // const image = document.getElementById('image')这是获取图片的DOM节点,但是在vue中是通过ref来获取的,所以这里需要进行一下更改
      const image = this.$refs['preview-image']
      // 下一步是初始化裁切器new了一个cropper,并把获取的DON当成参数给传了进去,这一步的作用是初始化裁切器
      this.cropper = new Cropper(image, {
        aspectRatio: 16 / 9,
        crop (event) {
          console.log(event.detail.x)
          console.log(event.detail.y)
          console.log(event.detail.width)
          console.log(event.detail.height)
          console.log(event.detail.rotate)
          console.log(event.detail.scaleX)
          console.log(event.detail.scaleY)
        }
      })
    },

(2)销毁裁切器,重新初始化

详解:关闭dialog之后,销毁这个裁切器,再次打开的时候就会重新初始化(用到dialog的一个方法closed)

<el-dialog
    title="提示"
    :visible.sync="dialogVisible"
    width="30%" :append-to-body="true" @opened="onDialogOpened" @closed="onDialogClosed">
      <div class="preview-image-wrap">
        <img class="preview-image" :src="previewImage" alt="" ref="preview-image">
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
 data () {
    return {
      cropper: null
    }
  }
methods: {
    onSubmit () {
    onDialogOpened () {
      // const image = document.getElementById('image')这是获取图片的DOM节点,但是在vue中是通过ref来获取的,所以这里需要进行一下更改
      const image = this.$refs['preview-image']
      // 下一步是初始化裁切器new了一个cropper,并把获取的DON当成参数给传了进去,这一步的作用是初始化裁切器
      this.cropper = new Cropper(image, {
        aspectRatio: 16 / 9,
        crop (event) {
          console.log(event.detail.x)
          console.log(event.detail.y)
          console.log(event.detail.width)
          console.log(event.detail.height)
          console.log(event.detail.rotate)
          console.log(event.detail.scaleX)
          console.log(event.detail.scaleY)
        }
      })
    },
    onDialogClosed () {
      // 对话框关闭,销毁裁切器
      this.cropper.destroy()
    }
  }
}

一定要注意这两种更新方法是怎么进行的,位置放在哪里

2.裁切器的配置:

一;

(1)注释掉一些不用的代码比如crop (event)

(2) aspectRatio: 16 / 9这是用来调整裁切的比例的

onDialogOpened () {
      if (this.cropper) {
        // replace
        this.cropper.replace(this.previewImage)
        return
      }
      // const image = document.getElementById('image')这是获取图片的DOM节点,但是在vue中是通过ref来获取的,所以这里需要进行一下更改
      const image = this.$refs['preview-image']
      // 下一步是初始化裁切器new了一个cropper,并把获取的DON当成参数给传了进去,这一步的作用是初始化裁切器
      this.cropper = new Cropper(image, {
        // aspectRatio这是裁切器的比例    16 :9
        // 当你移动裁切器的时候会触发调用方法crop方法,但是我们不怎么用,所以给注释掉了
        aspectRatio: 16 / 9,
        // crop (event) {
        //   console.log(event.detail.x)
        //   console.log(event.detail.y)
        //   console.log(event.detail.width)
        //   console.log(event.detail.height)
        //   console.log(event.detail.rotate)
        //   console.log(event.detail.scaleX)
        //   console.log(event.detail.scaleY)
        // }
      })
    }

二;属性

(1)viewMode:限制画布和容器之间的关系

(2)dragMode:裁切区域形成的模式,一般选为none

封装好的属性:注意这些属性写的位置
onDialogOpened () {
      if (this.cropper) {
        // replace
        this.cropper.replace(this.previewImage)
        return
      }
      const image = this.$refs['preview-image']
      this.cropper = new Cropper(image, {
        // aspectRatio这是裁切器的比例    16 :9
        aspectRatio: 16 / 9,
        viewMode: 1,
        dragMode: 'none',
        // cropBoxMovable意思是不允许改变裁切器的大小,就是1:1
        cropBoxMovable: true,
        // background裁切器的背景
        background: false
        // }
      })
    }

3.图片裁切-获取裁切的结果

通过方法getCroppedCanvas()
此处的file是经过裁切之后获得的图片结果

this.user.photo = res.data.data.photo渲染的时候这个方法有些慢

onUpdatePhoto () {
      // 获取裁切的图片对象
      this.cropper.getCroppedCanvas().toBlob(file => {
        const fd = new FormData()
        fd.append('photo', file)
        // 请求提交 fd
        updateUserPhoto(fd).then(res => {
          // 关闭对话框
          this.dialogVisible = false
          // 更新视图展示
          this.user.photo = res.data.data.photo
        })
      })

第二种方法

this.user.photo = window.URL.createObjectURL(this)

这是本地有裁切结果,这样做速度更快一点


```javascript
 onUpdatePhoto () {
      // 获取裁切的图片对象
      this.cropper.getCroppedCanvas().toBlob(file => {
        const fd = new FormData()
        fd.append('photo', file)
        // 请求提交 fd
        updateUserPhoto(fd).then(res => {
          // 关闭对话框
          this.dialogVisible = false
          // 更新视图展示
          this.user.photo = window.URL.createObjectURL(this)
          // this.user.photo = res.data.data.photo
        })
      })
      // 请求更新用户头像
      // 关闭对话框
      // 更新视图的展示
    }

图片预览的操作过程
思路:通过input标签的file类型拿到图片,然后再把图片给了电脑本地,然后电脑本地再通过途径src给了img标签
(1)写出type=“file”的input标签

```javascript
<input type="file" @change="onFileChange" ref="file">

(2)在input标签下写上一个img标签
每个标签都有一个ref,这是vue操作dom的方式

<input type="file" @change="onFileChange" ref="file">
<img width="100" ref="preview-image">

(3)给input绑定一个change事件,当发生改变的时候会触发的事件
代码解释:
1.获取input的文件对象
this. r e f s . f i l e 是 用 来 操 作 i n p u t 的 d o m , . f i l e s [ 0 ] 就 可 以 拿 到 图 片 文 件 了 c o n s t f i l e = t h i s . refs.file是用来操作input的dom,.files[0]就可以拿到图片文件了 const file = this. refs.fileinputdom.files[0]constfile=this.refs.file.files[0]
2.将图片给了电脑本地
const blob = window.URL.createObjectURL(file)
3.再将本地的电脑图片给了img的src标签
this. r e f s [ ′ p r e v i e w − i m a g e ′ ] . s r c = b l o b 4. 为 了 防 止 用 户 选 择 同 一 个 文 件 时 , 不 触 发 事 件 , 将 i n p u t 标 签 中 的 内 容 进 行 清 空 t h i s . refs['preview-image'].src = blob 4.为了防止用户选择同一个文件时,不触发事件,将input标签中的内容进行清空 this. refs[previewimage].src=blob4.inputthis.refs.file.value = ‘’

onFileChange () {
      // 获取文件对象
      const file = this.$refs.file.files[0]
      // 图片预览
      // window.URL.createObjectURL(file)目的是为了将文件对象传进去
      const blob = window.URL.createObjectURL(file)
      // this.$refs['preview-image']是为了拿到图片的dom 
      this.$refs['preview-image'].src = blob
      // 防止用户选择同一个文件,不触发事件
      // this.$refs.file这个操作拿到的input的dom
      this.$refs.file.value = ''
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Realistic-er

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值