微信小程序第四篇:生成图片并保存到手机相册

news2025/1/13 13:50:40

系列文章传送门:

微信小程序第一篇:自定义组件详解

微信小程序第二篇:七种主流通信方法详解

微信小程序第三篇:获取页面节点信息

目录

一、封装分享组件

二、定义用户授权方法

三、调用流程


首先我们看一下要完成的效果:

 

这种场景还是非常常见的,点击分享的时候我们可以转发给好友,或者生成当前页的海报图片保存到手机相册中。分享给好友这个功能可以通过  button 的 open-type 方式实现,那自动保存图片到本地该如何实现呢,让我们来看一看吧:

一、封装分享组件

首先我们要封装一个分享的组件,这样方便在其他的页面中复用。这样就大大减少了代码的冗余,

在 components 文件夹中新建一个组件,下面是完整代码

share.wxml:

<!-- 底部自定义分享菜单栏 -->
<view class="share-sheet-mask flex-column" hidden="{{!showShareSheet}}" catchtap="closeShareSheet">
  <view class="share-sheet">
    <view class="items flex-row">
      <view class="item flex-column">
        <button class="ico flex-row" open-type="share">
          <image class="img wx-ico" src="../../images/ico_wx.svg"></image>
        </button>
        <view class="desc">微信好友</view>
      </view>
      <view class="item flex-column">
        <button class="ico flex-row" catchtap="genPlayBill">
          <image class="img img-ico" src="../../images/ico_img.svg"></image>
        </button>
        <view class="desc">生成海报</view>
      </view>
    </view>
    <view class="cancel-share-sheet">取消</view>
  </view>
</view>

 share.js:

Component({
  /**
   * 组件的属性列表
   */
  properties: {

  },
  /**
   * 组件的初始数据
   */
  data: {
    showShareSheet: false
  },
  /**
   * 组件的方法列表
   */
  methods: {
    openShareSheet() {
      this.setData({showShareSheet: true})
    },
    closeShareSheet() {
      this.setData({showShareSheet: false});
    },
    genPlayBill() {
      this.triggerEvent('genPlayBill')
    },
  }
})

在点击生成海报的时候,我们向父组件发送了一个事件来调用 genPlayBill 方法,因为这个方法显然不应该在当前组件内定义,应该根据不同场景来定义我们只需要调用它就可以了。

share.wxss:

.flex-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
}

.flex-row {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.share-sheet-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.60);
  z-index: 101;
  justify-content: flex-end;
}

.share-sheet-mask .share-sheet {
  padding:0 24rpx;
  background: #f1f1f1;
  border-radius: 16rpx 16rpx 0px 0px;
  width: 100%;
  box-sizing: border-box;
}
.share-sheet-mask .share-sheet .items {
  padding: 48rpx 0 31rpx 0;
  justify-content: space-around;
  border-bottom: 0.5px solid rgba(39,36,71,0.20);
}
.share-sheet-mask .share-sheet .items .item{
  text-align: center;
}
.share-sheet-mask .share-sheet .items .item .ico {
  width: 80rpx;
  height: 80rpx;
  background: #ffffff;
  border-radius: 50%;
  box-shadow: 0 0 12rpx 0 rgba(204,204,204,0.60);
  padding: 0;
  margin: 0;
  padding: 0;
}
/*去除button的默认黑边框*/
.share-sheet-mask .share-sheet .items .item .ico::after{
  border: none;
}
.share-sheet-mask .share-sheet .items .item .ico .img {
  margin: auto;
}
.share-sheet-mask .share-sheet .items .item .ico .wx-ico {
  width: 52rpx;
  height: 40rpx;
}
.share-sheet-mask .share-sheet .items .item .desc {
  font-size: 24rpx;
  font-family: PingFangSC, PingFangSC-Regular;
  color: #6d6d6d;
  margin-top: 14rpx;
}
.share-sheet-mask .share-sheet .items .item .ico .img-ico {
  width: 44rpx;
  height: 44rpx;
}
.share-sheet-mask .share-sheet .cancel-share-sheet {
  margin: 31rpx auto 80rpx auto;
  font-size: 32rpx;
  font-family: PingFangSC, PingFangSC-Regular;
  color: #272447;
  text-align: center;
}

二、定义用户授权方法

刚刚我们封装了顶部的分享组件,那现在就要去定义保存图片到相册的方法了,我们写代码的时候一定要考虑清楚这段代码是否是可复用的,是否应该剥离出去。显然保存图片到相册这个方法我们应该写在 utils 目录中,因为有很多其他的场景都可以用这个方法,那我们就封装一个公用方法,参数就是图片的地址,成功的回调函数和失败的回调函数。

最复杂的就是用户授权了,我们一起看一下代码结构:

const saveImgToPhotos = (imgPath, succCallback, failedCallback) => {
  
    wx.getSetting ({ // 查询所有授权
        success(res) {
            if (res.authSetting['scope.writePhotosAlbum']) { // 用户已经授权
                save() // 执行保存函数
            }else { // 未授权
                wx.authorize({ scope: 'scope.writePhotosAlbum', 
                  success() {  // 用户同意授权
                    save()  // 执行保存函数
                  },
                  fail(err) {  // 用户拒绝授权
                    if (err && err.errMsg.endsWith("auth deny")) { 
                      wx.showModal({
                        title: '授权添加到相册',
                        content: '需要获取您的添加相册权限,请确认授权,否则分享功能无法正常使用',
                        success: function (resolve) {  
                          if (resolve.confirm) { // 用户同意设置授权
                            wx.openSetting({
                              success(res) {
                                if (res && res.authSetting['scope.writePhotosAlbum']) {
                                  save()  // 执行保存函数
                                }
                              },
                              fail(res) {   // 用户拒绝设置授权
                                console.log(res)
                                failedCallback('没有权限,保存失败')
                              }
                            })
                          } else {  // 用户拒绝设置
                            failedCallback('没有权限,保存失败')
                          }
                        }
                      })
                    } else {
                      failedCallback(err && err.errMsg || '保存失败')
                    }
                  }
                })
            }
        },
    })
  }
  

通过 wx.authorize() 来申请权限的方式是比较繁琐的。因为它的状态比较多,大致可分为:

  1. 用户未接受或拒绝过此权限,会弹窗询问用户,用户点击同意 —— 可调用相应接口。
  2. 用户未接受或拒绝过此权限,会弹窗询问用户,用户点击拒绝 —— 打开设置页面。
  3. 如果用户已授权 —— 可调用相应接口。
  4. 用户已拒绝授权 —— 打开设置页面。

上述情况的2/4是需要小伙伴们结合 wx.openSetting() 来帮助用户进行二次授权的。

搞定了用户授权这个麻烦事后,下面就是定义我们的 save 保存函数了,这个就很简单了:

let save = function () {
      wx.saveImageToPhotosAlbum({
        filePath: imgPath,
        success() {
          succCallback()
        },
        fail(res){
          failedCallback(res)
        }
      })
    }

把这段代码添加到 saveImgToPhotos 方法中就ok了,调用 wx.saveImageToPhotosAlbum 方法,参数就是我们传进来的图片地址,成功的话就执行成功的回调,失败就执行失败的回调。

下面是官方的文档说明:

 

三、调用流程

下面我们就把组件,方法这些东西引入到我们的页面中。在页面的 json 文件中引入组件路径。

把组件引入页面wxml中:

<share-sheet id="share-sheet" catch:genPlayBill="genTimelineImage" />

这里的方法就是点击生成海报的时候调用的父组件的方法。

当点击分享的时候展示分享组件:

openShareSheet(e) {
        this.selectComponent("#share-sheet").openShareSheet()
    },

在这里通过选择器可以直接调用子组件中的方法,来控制分享组件的显示与隐藏。

genTimelineImage(e) {
        wx.showLoading({
          title: "海报生成中",
          icon: "loading",
          mask: true,
        })
        const imgSrc = `路径`
        wx.getImageInfo({
          src: imgSrc,
        })
          .then((res) => {
            wx.hideLoading()
            this.imgTempPath = res.path
            this.saveTimelineImg()
          })
          .catch((err) => console.log(err))
      },
    
      saveTimelineImg: function () {
        saveImgToPhotos(this.imgTempPath, function(){
          this.selectComponent("#share-sheet").closeShareSheet()
        }.bind(this), function(errMsg) {
          this.selectComponent("#share-sheet").closeShareSheet()
        }.bind(this))
      },

当我们点击生成海报调用 genTimelineImage 方法的时候,通过 wx.getImageInfo 方法读取想要保存图片的临时下载路径,把他保存到外部定义的一个变量中,这样方便我们在 utils 目录中定义的 saveImgToPhotos 方法调用。这样我们整个的流程就over啦!

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

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

相关文章

地理空间开发包 TatukGIS Developer Kernel 11.72.X Crack

TatukGIS Developer Kernel (DK) 是专业级 GIS SDK&#xff08;软件开发工具包&#xff09;&#xff0c;各行各业的客户都使用它来开发自定义 GIS 应用程序或向现有产品添加地理空间功能。DK 可作为多个 SDK 版本使用&#xff0c;每个版本都针对特定的开发平台进行本地编译&…

胡扯系列之私人AI助手系统的分析与设计

背景 随着时代的发展&#xff0c;计算机算力的提升和近些年来AI模型的井喷以及发展。人工智能应用已经深入我们的日常生活。如人脸识别&#xff0c;无人驾驶等等&#xff0c;同时为了更好地与用户进行交互&#xff0c;完成特定功能&#xff0c;智能对话助手应运而生。如今大量…

某宝付费买的价值上万的60G的Python学习资源,0基础轻松赚钱到手软,请低调使用,禁止外传

前言 你是否 还在为升职加薪发愁&#xff1f; 苦于领导看不到自己更多长处&#xff1f; 还在为房贷&#xff0c;车贷&#xff0c;生计而发愁&#xff1f; 苦于不上班如何轻松赚快钱补贴家用&#xff1f; 为了帮助财务、设计、运营、策划、销售、HR、金融从业者、电商从业…

【单目3D目标检测】MonoFlex论文精读与代码解析

文章目录PrefaceAbstractContributionsPipelineProblem DefinitionDecoupled Representations of ObjectsInside & Outside ObjectsEdge FusionLossVisual Properties Regression2D DetectionDimension EstimationOrientation EstimationKeypoint EstimationAdaptive Depth…

Docker网络模式与配置

目录 &#x1f388;&#x1f388;1. Docker网络模式&#x1f3c3;‍♂️&#x1f3c3;‍♂️ &#x1f3c3;‍♂️&#x1f3c3;‍♂️2. 外部访问docker容器&#x1f3c3;‍♂️&#x1f3c3;‍♂️ &#x1f388;&#x1f388;3. 创建自定义网络&#xff1a;&#xff08;设…

尚医通 (三十一) --------- 手机登录

目录一、登录需求1. 登录效果2. 登录需求二、登录1. 搭建 service-user 模块2. 添加用户基础类3. 登录 API 接口4. 生成 token5. 阿里云短信6. 登录前端7. 登录全局事件8. myheader.vue 完整代码三、用户认证与网关整合一、登录需求 1. 登录效果 2. 登录需求 ① 登录采取弹出…

Python爬虫实战,requests+time模块,爬取某招聘网站数据并保存csv文件(附源码)

前言 今天给大家介绍的是Python爬取某招聘网站数据并保存本地&#xff0c;在这里给需要的小伙伴们代码&#xff0c;并且给出一点小心得。 首先是爬取之前应该尽可能伪装成浏览器而不被识别出来是爬虫&#xff0c;基本的是加请求头&#xff0c;但是这样的纯文 本数据爬取的人会…

ImmunoChemistry丨艾美捷抗体夹心ELISA开发试剂盒说明书

使用ImmunoChemistry艾美捷抗体夹心ELISA开发试剂盒评估检测可行性并优化ELISA性能参数。抗体夹心ELISA开发试剂盒提供了八种特殊配制的ELISA溶液和一个模板&#xff0c;用于抗体夹心ELISA测试的初始开发和优化。全面的ELISA开发手册提供了评估初始检测可行性和优化ELISA性能参…

关于 npm run buildprod 报错问题 :文件名、目录名或卷标语法不正确

引言 vue开发基本完成后进行打包时出现错误&#xff0c;这个错误以前没有遇到过&#xff0c;所以在这里激励 参考文章1 参考文章2 问题描述 在idea中运行npm run build:prod打包vue时出现报错 E:\Allworkspaces\idea-workspace\Project\vue-project\my-blog\vue-admin-te…

代码随想录第三天

专题&#xff1a;链表 题目&#xff1a;移除链表元素 题意&#xff1a;删除链表中等于给定值 val 的所有节点。 示例 &#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5] 解题思想&#xff1a; 我们为了统一操作&#xff0c;我们给链表…

身份证实名认证API接口有什么意义与作用?

身份证实名认证API接口有什么意义&#xff1f; 中国公民的身份证是一种对外证明自己身份的有效证件&#xff0c;随着国家对实名制要求的落实&#xff0c;工作与生活中许多场景都会需要进行身份验证。比如出门外出乘座火车与飞机时、注册互联网络平台时、网络游戏与购物时等等&a…

微信小程序怎么注册?【微信小程序制作】

即使在目前小程序盛行的时代&#xff0c;仍然有很多人在问微信小程序怎么注册、微信小程序怎么做的问题&#xff0c;也证明了我们对于微信小程序的需求依然巨大。那么微信小程序怎么注册呢&#xff1f;下面给大家简单介绍。 步骤1&#xff1a;注册小程序账号 我们在微信公众平…

启封化工行业管理方案—危化品的管理(1)

联合国危险品编码管理 什么是危化品&#xff1f; 危化品是指可能伤害人、其他生物体、财产或环境的固体、液体或气体。这些危险品在运输时始终受到规章制度的约束。运输这些危险品的团队是训练有素的专业人员。使用标签时&#xff0c;存储标签的容器或存储位置通常用菱形标牌标…

2022年疫情下的卡塔尔世界杯,你看了么,盘点一下爆冷的赛事

卡塔尔世界杯卡塔尔世界杯世界杯出现的爆冷比赛沙特阿拉伯 VS 阿根廷&#xff08;1:2&#xff09;德国 VS 日本 (1:2)比利时 VS 摩洛哥 (0:2)摩洛哥VS 加拿大 (2:1)日本 VS 西班牙 &#xff08;2:1&#xff09;摩洛哥 VS 西班牙(3:0)总结卡塔尔世界杯 卡塔尔世界杯有32个国家参…

数据结构与算法(Java版) | 几个经典的算法面试题(下)

上一讲&#xff0c;我给大家介绍了两个经典算法面试题&#xff0c;即字符串匹配问题和汉诺塔游戏&#xff0c;这一讲&#xff0c;我再来给大家介绍两个经典算法面试题&#xff0c;它们就是八皇后问题和马踏棋盘算法&#xff0c;注意&#xff0c;马踏棋盘算法也被称为骑士周游问…

springsecurity--Config层代码常用代码指令

前提搭建 使我们的类继承于WebSecurityConfigurerAdapter这个类 同时调用service还有新建一个bean方法 Bean public PasswordEncoder getPassword() {return new BCryptPasswordEncoder(); } 这个代码是可以自定义账户和密码 自定义登录账户和密码写在service类中 下方的红框…

SSM框架-SSM整合

目录 1 ContextLoaderListener 2 准备工作 3 配置web.xml 4 配置springmvc.xml 5 配置spring.xml 6 Spring整合MyBatis 7 配置log4j.xml 8 配置事务 9 测试功能 9.1 创建pojo类 9.2 员工列表功能 9.3 分页数据 9.4 分页相关超链接 1 ContextLoaderListener Spring提…

安卓玩机搞机技巧综合资源-----卸载内置软件 获取root权限 刷写第三方ROM【六】

接上篇 安卓玩机搞机技巧综合资源------如何提取手机分区 小米机型代码分享等等 【一】 安卓玩机搞机技巧综合资源------开机英文提示解决dm-verity corruption your device is corrupt. 设备内部报错 AB分区等等【二】 安卓玩机搞机技巧综合资源------EROFS分区格式 小米红…

985、211毕业一年,面试八家大厂,四面拿美团offer(Java后端)

自我介绍 本人三年开发&#xff0c;985硕士&#xff0c;211本科&#xff0c;专业都是软件工程&#xff0c;一直投的是Java后台开发&#xff0c;只投过一次网易的测试&#xff0c;技术不是太牛&#xff0c;但是比较努力。实验室没有项目&#xff0c;so项目经验是0&#xff0c;在…

openssl自动批量生成证书

使用bash批处理程序自动生成证书信息。 1、在linux系统创建一个文件夹 $ mkdir my_cert 2、创建CA证书以及私钥 $ cd my_cert $ openssl genrsa -out CA_Private.key 2048 $ openssl req -x509 -new -nodes -key CA_Private.key -sha256 -days 365 -out CA_Certificate.p…