小言_互联网的博客

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

1144人阅读  评论(0)

系列文章传送门:

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

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

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

目录

一、封装分享组件

二、定义用户授权方法

三、调用流程


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

 

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

一、封装分享组件

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

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

share.wxml:


  
  1. <!-- 底部自定义分享菜单栏 -->
  2. <view class="share-sheet-mask flex-column" hidden="{{!showShareSheet}}" catchtap="closeShareSheet">
  3. <view class="share-sheet">
  4. <view class="items flex-row">
  5. <view class="item flex-column">
  6. <button class="ico flex-row" open-type="share">
  7. <image class="img wx-ico" src="../../images/ico_wx.svg"> </image>
  8. </button>
  9. <view class="desc">微信好友 </view>
  10. </view>
  11. <view class="item flex-column">
  12. <button class="ico flex-row" catchtap="genPlayBill">
  13. <image class="img img-ico" src="../../images/ico_img.svg"> </image>
  14. </button>
  15. <view class="desc">生成海报 </view>
  16. </view>
  17. </view>
  18. <view class="cancel-share-sheet">取消 </view>
  19. </view>
  20. </view>

 share.js:


  
  1. Component({
  2. /**
  3. * 组件的属性列表
  4. */
  5. properties: {
  6. },
  7. /**
  8. * 组件的初始数据
  9. */
  10. data: {
  11. showShareSheet: false
  12. },
  13. /**
  14. * 组件的方法列表
  15. */
  16. methods: {
  17. openShareSheet( ) {
  18. this. setData({ showShareSheet: true})
  19. },
  20. closeShareSheet( ) {
  21. this. setData({ showShareSheet: false});
  22. },
  23. genPlayBill( ) {
  24. this. triggerEvent( 'genPlayBill')
  25. },
  26. }
  27. })

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

share.wxss:


  
  1. .flex-column {
  2. display: flex;
  3. flex-direction: column;
  4. align-items: center;
  5. justify-content: space-between;
  6. }
  7. .flex-row {
  8. display: flex;
  9. flex-direction: row;
  10. align-items: center;
  11. justify-content: space-between;
  12. }
  13. .share-sheet-mask {
  14. position: fixed;
  15. top: 0;
  16. left: 0;
  17. right: 0;
  18. bottom: 0;
  19. background: rgba( 0, 0, 0, 0.60);
  20. z-index: 101;
  21. justify-content: flex-end;
  22. }
  23. .share-sheet-mask .share-sheet {
  24. padding: 0 24rpx;
  25. background: #f1f1f1;
  26. border-radius: 16rpx 16rpx 0px 0px;
  27. width: 100%;
  28. box-sizing: border-box;
  29. }
  30. .share-sheet-mask .share-sheet .items {
  31. padding: 48rpx 0 31rpx 0;
  32. justify-content: space-around;
  33. border-bottom: 0.5px solid rgba( 39, 36, 71, 0.20);
  34. }
  35. .share-sheet-mask .share-sheet .items .item{
  36. text-align: center;
  37. }
  38. .share-sheet-mask .share-sheet .items .item .ico {
  39. width: 80rpx;
  40. height: 80rpx;
  41. background: #ffffff;
  42. border-radius: 50%;
  43. box-shadow: 0 0 12rpx 0 rgba( 204, 204, 204, 0.60);
  44. padding: 0;
  45. margin: 0;
  46. padding: 0;
  47. }
  48. /*去除button的默认黑边框*/
  49. .share-sheet-mask .share-sheet .items .item .ico ::after{
  50. border: none;
  51. }
  52. .share-sheet-mask .share-sheet .items .item .ico .img {
  53. margin: auto;
  54. }
  55. .share-sheet-mask .share-sheet .items .item .ico .wx-ico {
  56. width: 52rpx;
  57. height: 40rpx;
  58. }
  59. .share-sheet-mask .share-sheet .items .item .desc {
  60. font-size: 24rpx;
  61. font-family: PingFangSC, PingFangSC-Regular;
  62. color: #6d6d6d;
  63. margin-top: 14rpx;
  64. }
  65. .share-sheet-mask .share-sheet .items .item .ico .img-ico {
  66. width: 44rpx;
  67. height: 44rpx;
  68. }
  69. .share-sheet-mask .share-sheet .cancel-share-sheet {
  70. margin: 31rpx auto 80rpx auto;
  71. font-size: 32rpx;
  72. font-family: PingFangSC, PingFangSC-Regular;
  73. color: #272447;
  74. text-align: center;
  75. }

二、定义用户授权方法

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

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


  
  1. const saveImgToPhotos = ( imgPath, succCallback, failedCallback) => {
  2. wx. getSetting ({ // 查询所有授权
  3. success( res) {
  4. if (res. authSetting[ 'scope.writePhotosAlbum']) { // 用户已经授权
  5. save() // 执行保存函数
  6. } else { // 未授权
  7. wx. authorize({ scope: 'scope.writePhotosAlbum',
  8. success( ) { // 用户同意授权
  9. save() // 执行保存函数
  10. },
  11. fail( err) { // 用户拒绝授权
  12. if (err && err. errMsg. endsWith( "auth deny")) {
  13. wx. showModal({
  14. title: '授权添加到相册',
  15. content: '需要获取您的添加相册权限,请确认授权,否则分享功能无法正常使用',
  16. success: function ( resolve) {
  17. if (resolve. confirm) { // 用户同意设置授权
  18. wx. openSetting({
  19. success( res) {
  20. if (res && res. authSetting[ 'scope.writePhotosAlbum']) {
  21. save() // 执行保存函数
  22. }
  23. },
  24. fail( res) { // 用户拒绝设置授权
  25. console. log(res)
  26. failedCallback( '没有权限,保存失败')
  27. }
  28. })
  29. } else { // 用户拒绝设置
  30. failedCallback( '没有权限,保存失败')
  31. }
  32. }
  33. })
  34. } else {
  35. failedCallback(err && err. errMsg || '保存失败')
  36. }
  37. }
  38. })
  39. }
  40. },
  41. })
  42. }

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

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

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

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


  
  1. let save = function ( ) {
  2. wx. saveImageToPhotosAlbum({
  3. filePath: imgPath,
  4. success( ) {
  5. succCallback()
  6. },
  7. fail( res){
  8. failedCallback(res)
  9. }
  10. })
  11. }

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

下面是官方的文档说明:

 

三、调用流程

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

把组件引入页面wxml中:

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

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

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


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

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


  
  1. genTimelineImage( e) {
  2. wx. showLoading({
  3. title: "海报生成中",
  4. icon: "loading",
  5. mask: true,
  6. })
  7. const imgSrc = `路径`
  8. wx. getImageInfo({
  9. src: imgSrc,
  10. })
  11. . then( (res) => {
  12. wx. hideLoading()
  13. this. imgTempPath = res. path
  14. this. saveTimelineImg()
  15. })
  16. . catch( (err) => console. log(err))
  17. },
  18. saveTimelineImg: function ( ) {
  19. saveImgToPhotos( this. imgTempPath, function( ){
  20. this. selectComponent( "#share-sheet"). closeShareSheet()
  21. }. bind( this), function( errMsg) {
  22. this. selectComponent( "#share-sheet"). closeShareSheet()
  23. }. bind( this))
  24. },

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


转载:https://blog.csdn.net/qq_49900295/article/details/128252612
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场