HarmonyOS 鸿蒙Next:利用SaveButton组件显示图片到相册的方法demo,支持组件截图、url网络图片、base64格式图片。注意事项:1、不支持自定义SaveButton样式。2、带Scroll时下载按钮遮挡部分无法保存。

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next:利用SaveButton组件显示图片到相册的方法demo,支持组件截图、url网络图片、base64格式图片。注意事项:1、不支持自定义SaveButton样式。2、带Scroll时下载按钮遮挡部分无法保存。

cke_1330.png

import photoAccessHelper from ‘@ohos.file.photoAccessHelper’;
import fs from ‘@ohos.file.fs’;
import { common } from ‘@kit.AbilityKit’;
import { componentSnapshot, promptAction } from ‘@kit.ArkUI’;
import { image } from ‘@kit.ImageKit’;
import { BusinessError } from ‘@kit.BasicServicesKit’;
import { http } from ‘@kit.NetworkKit’;
import { util } from ‘@kit.ArkTS’;

@Entry @Component struct Page09 { inviteQrCodeID: string = “inviteQrCodeID” @State imageUrl: string = https://img1.baidu.com/it/u=1268271089,1175168242&fm=253&fmt=auto&app=120&f=JPEG?w=506&h=500 @State base64Str: string = ‘data:image/png;base64,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’

build() { Scroll() { Column({ space: 10 }) { Column({ space: 10 }) { Text(‘下载组件截图图片到相册’)

      Column() {
        Column() {
          Text(<span class="hljs-string"><span class="hljs-string">'标题测试'</span></span>).fontSize(<span class="hljs-string"><span class="hljs-string">'36lpx'</span></span>).height(<span class="hljs-string"><span class="hljs-string">'120lpx'</span></span>).fontColor(<span class="hljs-string"><span class="hljs-string">"#2E2E2E"</span></span>)
          QRCode(<span class="hljs-string"><span class="hljs-string">'https://www.huawei.com/'</span></span>)
            .width(<span class="hljs-string"><span class="hljs-string">'300lpx'</span></span>)
            .height(<span class="hljs-string"><span class="hljs-string">'300lpx'</span></span>)
            .margin({ top: <span class="hljs-string"><span class="hljs-string">'25lpx'</span></span> })
            .draggable(<span class="hljs-literal"><span class="hljs-literal">false</span></span>)
            .width(<span class="hljs-number"><span class="hljs-number">140</span></span>)
            .height(<span class="hljs-number"><span class="hljs-number">140</span></span>)
        }.padding({ left: <span class="hljs-string"><span class="hljs-string">'42lpx'</span></span>, right: <span class="hljs-string"><span class="hljs-string">'42lpx'</span></span>, bottom: <span class="hljs-string"><span class="hljs-string">'20lpx'</span></span> })

        Text(<span class="hljs-string"><span class="hljs-string">'点按下载保存至相册'</span></span>)
          .textAlign(TextAlign.Center)
          .padding({ left: <span class="hljs-string"><span class="hljs-string">'125lpx'</span></span>, right: <span class="hljs-string"><span class="hljs-string">'125lpx'</span></span> })
          .fontColor(<span class="hljs-string"><span class="hljs-string">"#4B4B4B"</span></span>)
          .fontSize(<span class="hljs-string"><span class="hljs-string">'32lpx'</span></span>)
          .margin({ bottom: <span class="hljs-string"><span class="hljs-string">'70lpx'</span></span> })
      }
      .id(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.inviteQrCodeID)
      .padding(<span class="hljs-string"><span class="hljs-string">'20lpx'</span></span>)
      .margin({ top: <span class="hljs-string"><span class="hljs-string">'30lpx'</span></span>, bottom: <span class="hljs-string"><span class="hljs-string">'30lpx'</span></span> })
      .backgroundColor(Color.White)
      .borderRadius(<span class="hljs-string"><span class="hljs-string">'30lpx'</span></span>)
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.Center)

      SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) =&gt; {
        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (result === SaveButtonOnClickResult.SUCCESS) {
          <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> context: common.UIAbilityContext = getContext(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>) as common.UIAbilityContext;
          <span class="hljs-comment"><span class="hljs-comment">// 免去权限申请和权限请求等环节,获得临时授权,保存对应图片</span></span>
          <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> helper = photoAccessHelper.getPhotoAccessHelper(context);
          <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
            <span class="hljs-comment"><span class="hljs-comment">// onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。</span></span>
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, <span class="hljs-string"><span class="hljs-string">'jpg'</span></span>);
            <span class="hljs-comment"><span class="hljs-comment">// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制</span></span>
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
            componentSnapshot.get(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.inviteQrCodeID).then((pixelMap) =&gt; {
              <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> packOpts: image.PackingOption = { format: <span class="hljs-string"><span class="hljs-string">'image/png'</span></span>, quality: <span class="hljs-number"><span class="hljs-number">100</span></span> }
              <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> imagePacker: image.ImagePacker = image.createImagePacker();
              <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> imagePacker.packToFile(pixelMap, file.fd, packOpts).finally(() =&gt; {
                imagePacker.release(); <span class="hljs-comment"><span class="hljs-comment">//释放</span></span>
                fs.close(file.fd);
                promptAction.showToast({
                  message: <span class="hljs-string"><span class="hljs-string">'图片已保存至相册'</span></span>,
                  duration: <span class="hljs-number"><span class="hljs-number">2000</span></span>
                });
              });
            })
          } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (error) {
            <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> err: BusinessError = error as BusinessError;
            console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`);
          }

        } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
          promptAction.showToast({
            message: <span class="hljs-string"><span class="hljs-string">'设置权限失败!'</span></span>,
            duration: <span class="hljs-number"><span class="hljs-number">2000</span></span>
          });
        }
      })
    }.borderWidth(<span class="hljs-number"><span class="hljs-number">1</span></span>).borderStyle(BorderStyle.Dotted).backgroundColor(Color.Pink).padding(<span class="hljs-string"><span class="hljs-string">'50lpx'</span></span>)

    Column({ space: <span class="hljs-number"><span class="hljs-number">10</span></span> }) {
      Text(<span class="hljs-string"><span class="hljs-string">'下载网络图片到相册'</span></span>)
      <span class="hljs-comment"><span class="hljs-comment">/**
       * 需要在  src/main/module.json5
       * 添加网络权限
       * {
       "module": {
       "requestPermissions": [
       {
       "name": "ohos.permission.INTERNET"
       },
       ],
       */</span></span>
      Image(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.imageUrl).width(<span class="hljs-string"><span class="hljs-string">'100lpx'</span></span>)

      SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) =&gt; {
        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (result === SaveButtonOnClickResult.SUCCESS) {
          <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> context: common.UIAbilityContext = getContext(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>) as common.UIAbilityContext;
          <span class="hljs-comment"><span class="hljs-comment">// 免去权限申请和权限请求等环节,获得临时授权,保存对应图片</span></span>
          <span class="hljs-comment"><span class="hljs-comment">// savePhotoToGallery(context);</span></span>
          <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> helper = photoAccessHelper.getPhotoAccessHelper(context);
          <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
            http.createHttp().request(
              <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.imageUrl,
              { expectDataType: http.HttpDataType.ARRAY_BUFFER }
            ).then(async (res) =&gt; {
              console.info(<span class="hljs-string"><span class="hljs-string">'res'</span></span>, <span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(res))
              <span class="hljs-comment"><span class="hljs-comment">// 将图片资源转为像素图(PixelMap)</span></span>
              <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> pixelMap = await image.createImageSource(res.result as <span class="hljs-built_in"><span class="hljs-built_in">ArrayBuffer</span></span>).createPixelMap()

              <span class="hljs-comment"><span class="hljs-comment">// onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。</span></span>
              <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, <span class="hljs-string"><span class="hljs-string">'jpg'</span></span>);
              <span class="hljs-comment"><span class="hljs-comment">// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制</span></span>
              <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
              <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> packOpts: image.PackingOption = { format: <span class="hljs-string"><span class="hljs-string">'image/png'</span></span>, quality: <span class="hljs-number"><span class="hljs-number">100</span></span> }
              <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> imagePacker: image.ImagePacker = image.createImagePacker();
              <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> imagePacker.packToFile(pixelMap, file.fd, packOpts).finally(() =&gt; {
                imagePacker.release(); <span class="hljs-comment"><span class="hljs-comment">//释放</span></span>
                fs.close(file.fd);
                promptAction.showToast({
                  message: <span class="hljs-string"><span class="hljs-string">'图片已保存至相册'</span></span>,
                  duration: <span class="hljs-number"><span class="hljs-number">2000</span></span>
                });
              });
            }).catch(() =&gt; {
              console.info(<span class="hljs-string"><span class="hljs-string">'catch'</span></span>)
            })
          } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (error) {
            <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> err: BusinessError = error as BusinessError;
            console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`);
          }

        } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
          promptAction.showToast({
            message: <span class="hljs-string"><span class="hljs-string">'设置权限失败!'</span></span>,
            duration: <span class="hljs-number"><span class="hljs-number">2000</span></span>
          });
        }
      })
    }.borderWidth(<span class="hljs-number"><span class="hljs-number">1</span></span>).borderStyle(BorderStyle.Dotted).backgroundColor(Color.Pink).padding(<span class="hljs-string"><span class="hljs-string">'50lpx'</span></span>)

    Column({ space: <span class="hljs-number"><span class="hljs-number">10</span></span> }) {
      Text(<span class="hljs-string"><span class="hljs-string">'下载base64图片到相册'</span></span>)
      Text(<span class="hljs-string"><span class="hljs-string">'注意1:有些base64的格式图片显示不出来,\n是因为前缀没加data:image/png;base64,'</span></span>).textAlign(TextAlign.Center)
      Text(<span class="hljs-string"><span class="hljs-string">"注意2:下载到相册的base64字符串不能有'data:image/jpeg;base64,'这样的前缀。所以我这里用正则去掉了前缀"</span></span>).textAlign(TextAlign.Center)
      SaveButton().onClick(async (event: ClickEvent, result: SaveButtonOnClickResult) =&gt; {
        <span class="hljs-keyword"><span class="hljs-keyword">if</span></span> (result === SaveButtonOnClickResult.SUCCESS) {
          <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> context: common.UIAbilityContext = getContext(<span class="hljs-keyword"><span class="hljs-keyword">this</span></span>) as common.UIAbilityContext;
          <span class="hljs-comment"><span class="hljs-comment">// 免去权限申请和权限请求等环节,获得临时授权,保存对应图片</span></span>
          <span class="hljs-comment"><span class="hljs-comment">// savePhotoToGallery(context);</span></span>
          <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> helper = photoAccessHelper.getPhotoAccessHelper(context);
          <span class="hljs-keyword"><span class="hljs-keyword">try</span></span> {
            <span class="hljs-comment"><span class="hljs-comment">// 正则表达式用于匹配 "data:image/*;base64," 这样的前缀</span></span>
            <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> prefixRegex = <span class="hljs-regexp"><span class="hljs-regexp">/^data:image\/[a-zA-Z]+;base64,/</span></span>;
            <span class="hljs-comment"><span class="hljs-comment">// 使用 replace 方法去除匹配到的前缀</span></span>
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> base64String = <span class="hljs-keyword"><span class="hljs-keyword">this</span></span>.base64Str.replace(prefixRegex, <span class="hljs-string"><span class="hljs-string">''</span></span>)
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> buffer: <span class="hljs-built_in"><span class="hljs-built_in">ArrayBuffer</span></span> =
              <span class="hljs-keyword"><span class="hljs-keyword">new</span></span> util.Base64Helper().decodeSync(base64String, util.Type.MIME).buffer as <span class="hljs-built_in"><span class="hljs-built_in">ArrayBuffer</span></span>;
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> imageSource = image.createImageSource(buffer);
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> pixelMap = await imageSource.createPixelMap({ editable: <span class="hljs-literal"><span class="hljs-literal">true</span></span> });

            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> opts: image.PackingOption = { format: <span class="hljs-string"><span class="hljs-string">"image/jpeg"</span></span>, quality: <span class="hljs-number"><span class="hljs-number">100</span></span> };
            <span class="hljs-comment"><span class="hljs-comment">// onClick触发后5秒内通过createAsset接口创建图片文件,5秒后createAsset权限收回。</span></span>
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, <span class="hljs-string"><span class="hljs-string">'jpg'</span></span>);
            <span class="hljs-comment"><span class="hljs-comment">// 使用uri打开文件,可以持续写入内容,写入过程不受时间限制</span></span>
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
            <span class="hljs-keyword"><span class="hljs-keyword">let</span></span> packOpts: image.PackingOption = { format: <span class="hljs-string"><span class="hljs-string">'image/png'</span></span>, quality: <span class="hljs-number"><span class="hljs-number">100</span></span> }
            <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> imagePacker: image.ImagePacker = image.createImagePacker();
            <span class="hljs-keyword"><span class="hljs-keyword">return</span></span> imagePacker.packToFile(pixelMap, file.fd, packOpts).finally(() =&gt; {
              imagePacker.release(); <span class="hljs-comment"><span class="hljs-comment">//释放</span></span>
              fs.close(file.fd);
              promptAction.showToast({
                message: <span class="hljs-string"><span class="hljs-string">'图片已保存至相册'</span></span>,
                duration: <span class="hljs-number"><span class="hljs-number">2000</span></span>
              });
            });
          } <span class="hljs-keyword"><span class="hljs-keyword">catch</span></span> (error) {
            <span class="hljs-keyword"><span class="hljs-keyword">const</span></span> err: BusinessError = error as BusinessError;
            console.error(`Failed to save photo. Code is ${err.code}, message is ${err.message}`);
          }

        } <span class="hljs-keyword"><span class="hljs-keyword">else</span></span> {
          console.info(`result:${<span class="hljs-built_in"><span class="hljs-built_in">JSON</span></span>.stringify(result)}`)
          promptAction.showToast({
            message: <span class="hljs-string"><span class="hljs-string">'设置权限失败!'</span></span>,
            duration: <span class="hljs-number"><span class="hljs-number">2000</span></span>
          });
        }
      })
    }
    .borderWidth(<span class="hljs-number"><span class="hljs-number">1</span></span>).borderStyle(BorderStyle.Dotted).backgroundColor(Color.Pink).padding(<span class="hljs-string"><span class="hljs-string">'50lpx'</span></span>)

  }.width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)
}.width(<span class="hljs-string"><span class="hljs-string">'100%'</span></span>)

} }<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

注意事项:

1、样式不支持自定义图标,试过用opacity修改透明度,然后添加背景来实现自定义样式,结果也失败了,opacity(1)点击生效,opacity(0.9)后点击按钮就不生效了。

参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs-V5/faqs-arkui-301-V5

2、如果带Scroll时,下载按钮被遮挡一部分,也无法保存到相册。

比如下面这样遮挡一点点下载按钮后,点击就没办法保存到相册了。

cke_78211.png

【参考方案】

1、官方文档:

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-security-components-savebutton-V5

2、PixelMap和base64的相互转换

参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-faqs-V5/faqs-image-15-V5



关于HarmonyOS 鸿蒙Next:利用SaveButton组件显示图片到相册的方法demo,支持组件截图、url网络图片、base64格式图片。注意事项:1、不支持自定义SaveButton样式。2、带Scroll时下载按钮遮挡部分无法保存。的问题,您也可以访问:https://www.itying.com/category-93-b0.html 联系官网客服。

4 回复

有要学HarmonyOS AI的同学吗,联系我:https://www.itying.com/goods-1206.html

使用SaveButton保存截图图片到相册的时候result为1,是什么原因

用我的例子有问题吗?如果没问题, 那可能的原因有, 你修改了SaveButton的透明度比如SaveButton.opacity(0.9), 你在SaveButton上面加了遮罩,按钮被阻挡了一部分。

已经搞定了,感谢🙏

回到顶部