微信小程序 实现上传图片前裁剪功能

news2024/9/21 10:19:54

前言

        技术支持: wx-cropper 裁剪

        总体思路是:安装完wx-cropper之后就它当成组件使用。在使用页面的地方引入组件就行。上传图片的逻辑不变,在 通过wx.chooseMedia() Api 拿到图片之后传递给子组件,子组件在拿到图片进行裁剪处理等操作之后,在把图片传递给父组件,父组件在拿到处理之后的图片,在进行自己之后的逻辑操作。简单来说就是------父组件上传图片-->子组件拿到图片进行处理-->处理的图片给父组件-->自己的逻辑操作

一. 引入wx-cropper

npm i @dw/wx-cropper

安装wx-cropper之后构建npm

二. 在需要使用的页面上引入

{
  "usingComponents": {
    "my-cropper": "@dw/wx-cropper"
  }
}

 三. 示例

        1. wxml代码

<button catchtap="handleuploadimg">上传图片</button>

<block wx:for="{{ fileList }}" wx:key="*this">
  <image src="{{ item }}" mode=""/>
</block>

<view class="layers" wx:if="{{cjtp}}">
    <my-cropper bind:close="hideCut" cutRatio="{{cutRatio}}" imageSrc="{{imageSrc}}" />
</view>

        2. wxss样式 

                这个是需要把裁剪功能组件覆盖到当前页面上

/* pages/upload/upload.wxss */
.layers{
  width: 100vw;
  height: 100vh;
  background-color: #00000080;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 10000000;
}

 

        3. js代码

                当选择完图片时,显示裁剪功能,以及把上传的图片传给组件。当用户裁剪完图片之后,会通过组件getImageInfo方法处理图片之后,在通过子组件向父组件传值的方法,把裁剪处理完之后图片传递给父组件 _this.triggerEvent('close', img);

// pages/upload/upload.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    fileList: [], //上传图片集合
    base64List: [], //base64集合
    delFileArr:[],  //删除的附件集合
    imgWidthslot: 0,
    imgHeightslot: 0,
    //裁剪信息
    cjtp: false,     //裁剪信息 这个控制裁剪功能的现实和隐藏
    cutRatio:0.75,  //裁剪比例
    imageSrc:'',    //个人图片
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {

  },
  // 上传图片
  handleuploadimg() {
    wx.chooseMedia({
      count: 1,
      mediaType: ['image'],
      sourceType: ['camera', 'album'],
      success: (res) => {
        // this.setData({
        //   fileList: res.tempFiles
        // })
        var tempFilePaths = res.tempFiles;
        for (let i in tempFilePaths) {
          let imagePath = tempFilePaths[i].tempFilePath; //原图的路径
          let size = tempFilePaths[i].size;      //原图大小
            //this.setData({
             // imageSrc:imagePath,
              //cjtp:true,
            //})
            //判断是否需要压缩
           if(size > this.data.size){
              this.setCanvasLoad(imagePath);
           }else{
            this.setData({
              imageSrc:imagePath,
              cjtp:true,
            })
          }
          
        }
      }
    })
  },
// 压缩图片
setCanvasLoad(obj){
    let imagePath = obj; //原图的路径
      const ctx = wx.createCanvasContext('myfirstCanvasSlot',this);
      let that = this;
      wx.showLoading({
        title: '图片压缩中...',
        mask: true
      }) //不需要你可以删掉
      // console.log(imagePath,'原图的路径')
      wx.getImageInfo({
        src:imagePath,
        success:(res)=>{
          // console.log(res,'获取图片的属性')
          // 图片原始尺寸
          let originWidth = res.width;
          let originHeight = res.height;
          // 最大尺寸限制,可通过设置宽高来实现图片压缩程度
          let maxWidth = 1920,
              maxHeight = 800;
          // 目标尺寸
          let targetWidth = originWidth,
              targetHeight = originHeight;
          // 图片尺寸超过200x150的限制
          if(originWidth > maxWidth || originHeight > maxHeight) {
              if(originWidth / originHeight > maxWidth / maxHeight) {
                  // 更宽,按照宽度限定尺寸
                  targetWidth = maxWidth;
                  targetHeight = Math.round(maxWidth * (originHeight / originWidth));
              } else {
                  targetHeight = maxHeight;
                  targetWidth = Math.round(maxHeight * (originWidth / originHeight));
              }
          }
          // canvas对图片进行缩放
          this.setData({
              imgWidthslot: targetWidth,
              imgHeightslot: targetHeight
          })

          // 压缩图片(绘制图像到画布)
          ctx.drawImage(imagePath,0,0,targetWidth,targetHeight);
          console.log(this.data.imgWidth)

          ctx.draw(false, ()=>{
            setTimeout(()=>{
              // canvas导出为图片路径
              wx.canvasToTempFilePath({
                canvasId: 'myfirstCanvasSlot',
                fileType: 'png', //支持jpg或png
                quality: 0.92, //图片质量
                success:(res1)=> {
                    wx.hideLoading();
                    // console.log(targetWidth,targetHeight,'targetHeight')
                    let compressedPath = res1.tempFilePath;
                    //将图片转化为base64
                    this.setData({
                      imageSrc:compressedPath,
                      cjtp:true,
                    })
                },
                fail:(res1)=>{
                  // console.log('图片压缩失败',res)
                  wx.hideLoading()
                  wx.showModal({
                    content: '图片压缩失败',
                    showCancel:false
                  })
                }
              },that)
            },200)
             
          })
        },
        fail: (res) => {
          wx.hideLoading()
          // console.log(res,'获取图片的属性失败');
          wx.showModal({
            content: '图片压缩失败',
            showCancel:false
          })
        }
      })
  },
  
  //关闭裁剪
  hideCut(e){
    let obj = e.detail;
    let fileList = this.data.fileList;
    let base64List = this.data.base64List;
    //是否已经截取
    if(obj){
      console.log('------obj', obj)
      wx.showLoading({
        title: '裁剪中',
      })
      fileList = [ obj.path ]
      wx.getFileSystemManager().readFile({
        filePath: obj.path,
        encoding: "base64",
        success: (res) => {
          
          wx.hideLoading(); //不需要你可以删掉
          base64List = [res.data]
          this.setData({
            base64List: base64List,
            fileList: fileList,
          })

          console.log('-----res-----', this.data.base64List, this.data.fileList)
        },
        fail: (res) => {

          wx.hideLoading(); //不需要你可以删掉
          wx.showModal({
            content: '图片裁剪失败',
            showCancel:false
          })
        }
      })
    }
    this.setData({
      cjtp:false,
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

父组件会通过hideCut方法 来拿到子组件传递过来的图片,然后在回显到页面上。 

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

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

相关文章

Day60力扣打卡

打卡记录 1682分了记录下&#xff0c;希望下回能突破1700捏。作为一个菜鸟&#xff0c;知道自己很菜&#xff0c;一步步走到现在还是很开心的&#xff0c;从以前的周赛稳定1题到稳定2题&#xff0c;到现在的时有时无的3题。每次刷题都期盼有所长进&#xff0c;虽然更多的时候收…

DockerCompose部署RabbitMQ集群

DockerCompose部署RabbitMQ集群 最近小黄在工作中正好需要部署RabbitMQ集群&#xff0c;借此来记录一下&#xff0c;也希望可以帮助到大家 前置条件 简单介绍一下咱们公司现有的条件以及想要达成的效果 服务器3台&#xff0c;3台都是属于一个专有网络中&#xff0c;也就是说3…

UDP特性之广播

UDP特性之广播 1. 广播的特点2. 设置广播属性3. 广播通信流程4. 通信代码总结 1. 广播的特点 广播的UDP的特性之一&#xff0c;通过广播可以向子网中多台计算机发送消息&#xff0c;并且子网中所有的计算机都可以接收到发送方发送的消息&#xff0c;每个广播消息都包含一个特殊…

单机环境下一人一单

优惠券秒杀 添加优惠卷 店铺发布优惠券又分为平价券和特价券, 平价券可以任意购买而特价券需要秒杀抢购(限制数量和时间) tb_voucher(平价券): 优惠券的基本信息 tb_seckill_voucher(秒杀券): 有voucher_id字段表示具有优惠卷的基本信息,此外还有库存,开始抢购时间,结束抢购…

世界第一个语言不通的人是如何沟通的?

引言&#xff1a;语言是人类交流的重要工具&#xff0c;但在人类历史的某个时刻&#xff0c;肯定会有这样一位勇敢的先驱&#xff0c;他成为了世界上第一个语言不通的人。那么在他面临交流难题时&#xff0c;他是如何与他人沟通的呢&#xff1f;本文将对此进行探索。主体&#…

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验&#xff08;七层代理&#xff09; 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器&#xff08;192.168.75.60:8080&#xff09; 多实例部署第二台Tomcat应用服务器&#xff08;192.168.75.70:80…

【超图】SuperMap iClient3D for WebGL/WebGPU —— 单体gltf模型与Blender中的方向对应关系

作者&#xff1a;taco 在很多包含动画的场景中&#xff0c;像模拟小人的行走、模拟火车的轨迹运行&#xff0c;又或者是模拟风力发电等等等。我们通常会加一些动画模型到里面。而有的时候可能会出现&#xff0c;这火车怎么倒着走啊&#xff01;这人怎么头朝下啊。这种方向的问题…

【MySQL】MySQL库的增删查改

文章目录 1.库的操作1.1创建数据库1.2创建数据库案例 2.字符集和校验规则2.1查看系统默认字符集以及校验规则2.2查看数据库支持的字符集2.3查看数据库支持的字符集校验规则2.4校验规则对数据库的影响 3.操纵数据库3.1查看数据库3.2显示创建语句3.3修改数据库3.4数据库删除3.5备…

DevOps搭建(五)-JDK安装详细步骤

1、官网下载 官方网站下载JDK&#xff0c;这里我们安装JDK8 https://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html 点击上图中的Java SE Downloads项目&#xff0c;也可直接点击下面链接进入&#xff1a; Java Downloads | Oracle 往下滚…

Android14创建Pixel6 Pro模拟器(一百七十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

C++设计模式-Builder 构建器

通过“对象创建” 模式绕开new&#xff0c;来避免对象创建&#xff08;new&#xff09;过程中所导致的紧耦合&#xff08;依赖具体类&#xff09;&#xff0c;从而支持对象创建的稳定。它是接口抽象之后的第一步工作。 一、动机 在软件系统中&#xff0c;有时候面临着“一个复…

STM32--Wi-Fi插座_风扇_灯

项目需求 两个互相通信的双方&#xff0c;波特率必须相同!!!!!! 通过 ESP8266 模块&#xff0c;实现手机控制 wifi 插座 / 风扇 / 灯。 项目设计 串口 1 用于与 ESP8266 通讯&#xff0c;串口 2 连接 PC &#xff0c;用于打印 log &#xff0c;查看系统状态。 项目实现 注意&a…

网络安全项目实战(四)--报文检测

8. TCP/UDP 段 目标 了解 TCP 段头的组织结构了解 UDP 段头的组织结构掌握 TCP/UDP 段的解析方式 8.1. UDP 段格式 下图是UDP的段格式&#xff08;该图出自[TCPIP]&#xff09;。 8.2. UDP头部 //UDP头部&#xff0c;总长度8字节// /usr/include/linux/udp.h struct udphdr …

拦截器实现指定的IP白名单进行访问规定的Controller

需求&#xff1a;只允许内网的IP&#xff08;也就是IP白名单&#xff09;进行访问VideoController和ImgController&#xff0c;其余的FontController可以随便访问不做限制 总体的项目结构&#xff1a; 1、先写好业务代码三个Controller 访问的路径分别是&#xff1a; /api/…

【三视图】咒语 生成人物

revAnimated_v122.safetensors 杰作&#xff0c;最佳质量&#xff0c;角色设计&#xff0c;三视图&#xff0c;前视图&#xff0c;侧视图&#xff0c;后视觉&#xff0c;呆萌&#xff0c;可爱&#xff0c;简单的背景&#xff0c; (badhandv4:1.4),ng_deepnegative_v1_75t,negat…

qt-C++笔记之模拟实现一个linux终端窗口

qt-C笔记之模拟实现一个linux终端窗口 code review! 文章目录 qt-C笔记之模拟实现一个linux终端窗口一.运行二.main.cpp三.不足&#xff0c;待改进点 一.运行 二.main.cpp 代码 #include <QApplication> #include <QPlainTextEdit> #include <QLineEdit>…

新版Spring Security6.2 - Digest Authentication

前言&#xff1a; 书接上文&#xff0c;上次翻译basic的这页&#xff0c;这次翻译Digest Authentication这页。 摘要认证-Digest Authentication 官网的警告提示&#xff1a;不应在应用程序中使用摘要式身份验证&#xff0c;因为它不被认为是安全的。最明显的问题是您必须以…

聊聊Java中的异常

什么是异常 关于Java的异常&#xff0c;我们认为符合大致分为以下几种情况: 程序逻辑运行结果不符合预期。程序执行时抛出各种exception。因为各种原因导致服务崩溃。 Java异常类体系结构如下图所示: Exception和Error的区别 Exception Exception或者Exception自类的异常对…

有关爬虫http/https的请求与响应

简介 HTTP协议&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;&#xff1a;是一种发布和接收 HTML页面的方法。 HTTPS&#xff08;Hypertext Transfer Protocol over Secure Socket Layer&#xff09;简单讲是HTTP的安全版&#xff0c;在HTT…

【亲测】获取百度智能云access_token并存储,百度智能云access_token有效期

百度智能云服务内置很多api接口&#xff08;文字识别&#xff0c;企业信息识别&#xff0c;等&#xff09;&#xff0c;所有百度智能云自带的接口都会用到百度的access_token 第一步&#xff1a;登录百度智能云管理中心 第二步&#xff1a;创建账户&#xff0c;完整身份认证 …