首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >5分钟搞定图片裁剪,上传

5分钟搞定图片裁剪,上传

作者头像
皮小蛋
发布2020-03-02 10:26:03
4.6K0
发布2020-03-02 10:26:03
举报
文章被收录于专栏:前端皮小蛋前端皮小蛋

先给大家看一下最终效果。

大多数功能都是由 Cropper.js封装好的,调整并制作了:

  • 上传图片
  • 对图片的裁剪以及调整(旋转、缩放)、
  • 实时预览
  • 将裁剪后的数据保存为blob发送至后端。

Q1:为什么选择Cropper.js和如何安装Cropper.js?

一开始制作这个需求思路有两个,使用canvas原生或者寻找现成的库,对比了一番觉得canvas实现时间耗费较长,且秉承着不重复造轮子的原则(其实是菜),决定使用Cropper.js。官方封装了很多参数、方法、事件,上手容易,文档阅读体验较好、而且便于扩展。

Cropper.js官方仓库+文档:github.com/fengyuanche…

Installation

npm install cropperjs

Q2:如何上传图片?

我们实现上述功能需要的核心HTMl部分只有:

    <!-- 1.一个用于获取上传文件的input,type="file",并且监听onchange事件  -->
    <input 
        type="file"     
        accept="image/*" 
        id="imgReader" 
        onchange="loadingImg"
        > 

    <!-- 2.一个用于给Cropper.js覆盖使用的img  -->
    <img id="cropImg">
    
    <!-- 3.两个用于预览的div  -->
    <div class="previewText">裁剪预览</div>
    <div class="previewBox"></div>

首先先将用于上传的input隐藏起来,我们并不需要它的样式

.inpuFile{
    display: none;
}

然后给你项目中的某个按钮添加一个点击事件,并且调用

    function uploadImg(){
            document.querySelector('#imgReader').click()
    },

即可打开上传文件的窗口,然后选择你需要的图片

Q3:如何将图片读取显示和使用Cropper.js添加裁剪控件?

上传文件成功后,会触发onchange事件,调用loadingImg()

//引入Cropper.js

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

const CROPPER = null    //创建一个cropper的全局对象 

function loadingImg(eve){
 //读取上传文件
    let reader = new FileReader();
    if(event.target.files[0]){
    
    //readAsDataURL方法可以将File对象转化为data:URL格式的字符串(base64编码)
        reader.readAsDataURL(eve.target.files[0]);
        reader.onload = (e)=>{
            let dataURL = reader.result;
            //将img的src改为刚上传的文件的转换格式
            document.querySelector('#cropImg').src = dataURL;  
            
            const image = document.getElementById('cropImg');  
            
            //创建cropper实例-----------------------------------------
            CROPPER = new Cropper(image, {
                aspectRatio: 16 / 16,
                viewMode:0,
                minContainerWidth:500,
                minContainerHeight:500,
                dragMode:'move',
                preview:[ document.querySelector('.previewBox'),
                        document.querySelector('.previewBoxRound')]
            })
        }
    }
   }
new Cropper方法:

new Cropper(element[, options])

第一个参数:element

  • 类型:HTMLImageElement 或 HTMLCanvasElement;
  • 作用:用于显示裁剪功能;

第二个参数(可选):

  • 类型: Object;
  • 作用:用于添加具体参数设置

我们需要用到的参数有:

{
    aspectRatio: 16 / 16,    //固定裁剪框的比例(横/竖),此处16/16则固定为正方形
    minContainerWidth:500,   //容器最小的宽度
    minContainerHeight:500,  //容器最小的高度
    dragMode:'move',         //设置裁剪框为可以移动
    preview:[ document.querySelector('.previewBox'),           //设置我们需要添加实时预览的地方
            document.querySelector('.previewBoxRound')]
            
    //更多参数请参照官方仓库...我们这里用不着
}

先忽略实时预览,完成到这里我们就可看到我们上传的图片以及裁剪功能:

Q4:如何进行实时预览?

上面创建cropper的时候,我们在选项中添加了

    preview:[ document.querySelector('.previewBox'),           
              document.querySelector('.previewBoxRound')]

preview就是用来设置我们需要实时预览的地方,但是设置完成之后要给上述的两个div添加一下样式,才可以正常显示

.previewBox,.previewBoxRound{
    box-shadow: 0 0 5px #adadad;
    width: 100px;
    height: 100px;
    margin-top: 30px;
    overflow: hidden;       /*这个超出设置为隐藏很重要,否则就会整个显示出来了*/
}
.previewBoxRound{
    border-radius: 50%;     /*设置为圆形*/     
}

Q5:如何获取裁剪数据并发送至后端?

function GetData(){
        //getCroppedCanvas方法可以将裁剪区域的数据转换成canvas数据
          CROPPER.getCroppedCanvas({
                maxWidth: 4096,
                maxHeight: 4096,
                fillColor: '#fff',
                imageSmoothingEnabled: true,
                imageSmoothingQuality: 'high',
            }).toBlob((blob) => {
               //然后调用浏览器原生的toBlob方法将canvas数据转换成blob数据
               //之后就可以愉快的将blob数据发送至后端啦,可根据自己情况进行发送,我这里用的是axios
                const formData = new FormData();
                // 第三个参数为文件名,可选填.
                formData.append('croppedImage', blob/*, 'example.png' */);
                let config = {
                    headers:{'Content-Type':'multipart/form-data'}
                }   
                this.$axios.post(flow_mission_UploadFile(),param,config)
                    .then((response)=>{ 
                        console.log(response)    
                    })
                    .catch((err)=>{
                        console.log(err)
                    })
            })
    }       
其他需要注意的地方:
1.裁剪框尺寸问题

裁剪部分默认会根据上传图片的大小进行改变

  • 解决图片过小的问题:
    //在new Cropper的参数中设置
    
    minContainerWidth:500,   //容器最小的宽度
    minContainerHeight:500,  //容器最小的高度
复制代码
  • 解决图片过大的问题: 给添加固定宽度样式
    #cropImg{
        height: 450px;
        width: 450px;
        box-shadow: 0 0 5px #adadad;
    }
2.重复上传的问题

再次上传不同图片的时候,还是出现原来的图片,只需要在上传文件的时候,对之前存在的CROPPER进行摧毁就可以了

    function uploadImg(){
            document.querySelector('#imgReader').click()
            if(CROPPER){
                CROPPER.destroy()
            }
    },3.其他功能的实现

这里列举几个我这里用到的

  • CROPPER.rotate(90) :旋转图片,单位为数字,90为顺时针旋转90度
  • CROPPER.zoom(0.1) :缩放图片,单位为数字,0.1为在原缩放基础上增加0.1倍
  • CROPPER.reset() :重置对图片的所有操作

还有很多其他方法和事件可以自行参照仓库,一个普通的上传头像功能就这样应该够用了!这里就不一一列举了。

谢谢大家。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端皮小蛋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Q1:为什么选择Cropper.js和如何安装Cropper.js?
  • Q2:如何上传图片?
  • Q3:如何将图片读取显示和使用Cropper.js添加裁剪控件?
    • new Cropper方法:
    • Q4:如何进行实时预览?
    • Q5:如何获取裁剪数据并发送至后端?
      • 1.裁剪框尺寸问题
        • 2.重复上传的问题
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档