在鸿蒙中如何把网络图片保存到相册中

配置ohos.permission.WRITE_IMAGEVIDEO权限

首先我们需要配置一下图片写入的权限,注意这个权限是受限权限,我们需要使用自动签名,但使用的DevEco Studio版本低于4.0 Release,在开发过程中使用了这个权限也叫ACL权限,则需要采用手动签名。请根据自己用的版本变换签名方式。

操作步骤

第一步

在module.json5文件中配置ohos.permission.WRITE_IMAGEVIDEO权限。示例代码如下:

{
  "name" : "ohos.permission.WRITE_IMAGEVIDEO",
  "reason": "$string:file_reason_desc",
  "usedScene": {
    "when":"always"
  }
}

具体位置如下:
在这里插入图片描述
配置好了这个权限之后,运行时会报一个错误,说你使用的权限是受限权限,没有签名不能使用。

第二步

那么我们就需要去配置一下签名了,我使用的DevEco Studio版本是5.0.3.100,所以我就直接使用自动签名了,如果有小伙伴使用的是4.0以下的版本,请使用手动签名。具体操作如下:
进入File > Project Structure… > Project > Signing Configs界面,勾选“Automatically generate signature”(如果是HarmonyOS工程,需同时勾选“Support HarmonyOS”),即可完成签名。如果未登录,请先单击Sign In进行登录,然后自动完成签名。
在这里插入图片描述
手动签名可参考鸿蒙开发中心

实现功能代码

配置好了这个权限后,就可以去est文件写代码了,示例代码如下:

import { abilityAccessCtrl, common } from '@kit.AbilityKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import fs from '@ohos.file.fs';
import { http } from '@kit.NetworkKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component struct Index {
@State message: string = 'Hello World'
private appContext: common.Context = getContext(this);
private atManager = abilityAccessCtrl.createAtManager();
 
build() {
   Row() {
     Column() {
       Text(this.message)
       .fontSize(50)
       .fontWeight(FontWeight.Bold)
      Button("保存图片")
      .margin({ top: 10 })
      .onClick(async (event: ClickEvent) => { 
          //申请权限并保存图片到图库
        try { 
        //申请相册管理模块权限'ohos.permission.WRITE_IMAGEVIDEO' 
         this.atManager.requestPermissionsFromUser(this.appContext, [ 'ohos.permission.WRITE_IMAGEVIDEO' ]).then(async () => { 
        //权限申请成功,保存到图库
        let context = getContext();
        //获取相册管理模块的实例,用于访问和修改相册中的媒体文件
        let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context); 
        // onClick触发后10秒内通过createAsset接口创建图片文件,10秒后createAsset权限收回
        let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
       // 创建媒体文件
       console.info('createAsset successfully, uri: ' + uri);
       let file = fs.openSync(uri, fs.OpenMode.READ_WRITE || fs.OpenMode.CREATE);
      let totalSize = 0;
      let httpRequest = http.createHttp();
       httpRequest.on("dataReceive", (data: ArrayBuffer) => {
      let writeLen = fs.writeSync(file.fd, data); 
      totalSize = totalSize + writeLen; });
      httpRequest.requestInStream('https://developer.huawei.com/allianceCmsResource/resource/HUAWEI_Developer_VUE/images/homeNew/next- pc.png',
       { method: http.RequestMethod.GET, connectTimeout: 3000, }, httpCode => {
         console.info('requestInStream HTTP CODE is', httpCode) })
          httpRequest.on("dataEnd", () => { 
          fs.close(file);
        promptAction.showDialog({ title: "下载图片结束,并保存至相册", message: `图片大小:${totalSize}字节` }) }) }) 
          } catch (err) { 
            console.error(`requestPermissionsFromUser call Failed! error: ${err.code}`); } }) }
          .width('100%') 
         }
       .height('100%') 
    } 
}

此代码仅供参考,里面保存的图片网址需要更换为咱们自己的噢~

还有最重要的一点,这个功能只能在真机运行时,可以看到保存的图片,在模拟器中保存的图片是空白的,咱也不知道是为啥,有没有懂哥,愿闻其详。

对了,这里没有提到申请网络权限ohos.permission.INTERNET,那是因为它不是受限权限,可直接在module.json5文件中配置即可,不需要其他操作。

这个是最近遇到的一点小问题,现在解决了,赶紧趁还熟悉,就出了这个博客,写鸿蒙的小伙伴们,拿走不谢~~,求赞,求赞,求赞,重要的事情说三遍

<think>嗯,用户想在鸿蒙系统中实现将animation.to生成的动态图片保存相册的方法。首先,我需要回忆一下相关的开发文档和API。根据提供的引用,特别是引用[3]提到了使用image.createPixelMapSync()和writePixelsSync来拼接长截图,这可能涉及到图像处理的部分。但用户需要的是动态图片,比如GIF或视频,而不仅仅是静态截图。 接下来,我需要确定鸿蒙系统是否支持将动画导出为动态图片格式。通常,这可能需要逐帧捕获动画,然后将这些帧编码成GIF或视频文件。引用[2]提到了animateTo函数,这可能用于控制动画,但保存动画可能需要捕获每一帧的图像数据。 另外,引用[3]中的方法是将图像片段写入PixelMap来生成长截图。或许类似的方法可以用于捕获动画的每一帧,然后将这些帧合并成动态图片。但需要注意,鸿蒙的API是否支持这样的操作,特别是动态图片的编码和保存。 用户的问题可能涉及到以下步骤:1. 逐帧捕获动画;2. 将帧数据保存为图像文件;3. 合并图像文件为动态格式;4. 使用相册保存API。需要检查是否有相关的图像处理库或API支持这些步骤,例如image模块是否有编码GIF的功能,或者是否需要第三方库。 此外,引用[4]提到使用Promise处理异步操作,这可能在进行文件保存时用到,确保异步操作的正确执行顺序。例如,在每帧捕获后异步保存,最后合并所有帧。 还需要考虑权限问题,应用是否有写入相册的权限,这需要在配置文件中声明,并动态请求用户授权。引用[3]中的SaveButton控件可能是一个安全控件,用于处理保存操作,但需要确认其是否支持动态图片格式。 可能遇到的问题包括:帧率控制、内存管理(大量帧可能导致内存不足)、动态图片编码的性能问题。需要建议用户进行性能优化,比如分批次处理帧或使用后台线程。 综上所述,实现步骤可能包括使用动画监听逐帧捕获,利用image模块处理每帧图像,使用编码库生成动态文件,最后调用相册保存接口,并处理权限和异步操作。</think>在鸿蒙系统开发中,将$animation.to$生成的动态效果保存为动态图片需要结合**动画帧捕获**和**图像编码技术**。以下是具体实现步骤及代码示例: --- ### 一、核心实现原理 1. **逐帧捕获**:通过动画插值监听器获取每一帧画面 2. **图像编码**:将帧序列编码为GIF/APNG等动态格式 3. **文件存储**:调用媒体库接口保存相册 --- ### 二、实现步骤 #### 1. 配置权限 在`module.json5`中添加相册写入权限: ```json "requestPermissions": [ { "name": "ohos.permission.WRITE_IMAGEVIDEO" } ] ``` #### 2. 创建动画控制器 ```typescript @State scale: number = 1; private anim = this.animation.create({ duration: 1000, curve: curves.springMotion() }); ``` #### 3. 逐帧捕获实现 ```typescript // 创建帧容器 private frameArray: image.PixelMap[] = []; // 设置动画监听 this.anim.onStart(() => { this.anim.onFrame((value: number) => { // 捕获当前帧画面 const captureOptions: image.ImageCaptureOptions = { quality: 100, format: image.ImageFormat.JPEG }; const framePixelMap = image.createPixelMapFromSurface(captureOptions); this.frameArray.push(framePixelMap); // 保存帧数据[^3] }); }); ``` #### 4. 动态图像编码 ```typescript async function encodeGIF() { const gifEncoder = new GifEncoder(800, 600); const output = new ByteArrayOutputStream(); gifEncoder.start(output); gifEncoder.setDelay(100); // 设置帧间隔 // 遍历所有帧 this.frameArray.forEach((pixelMap) => { const frameBitmap = await pixelMap.getBitmapInfo(); gifEncoder.addFrame(frameBitmap); // 添加单帧 }); gifEncoder.finish(); return output.toByteArray(); } ``` #### 5. 保存相册 ```typescript async function saveToGallery() { const gifData = await this.encodeGIF(); // 创建媒体资源 const mediaRequest: mediaLibrary.MediaAssetChangeRequest = await mediaLibrary.createMediaAssetChangeRequest(context); // 设置文件属性 mediaRequest.path = "Download/Animation/"; mediaRequest.displayName = `anim_${Date.now()}.gif`; // 写入文件内容 const file = await mediaRequest.getFileHandle(); await file.write(gifData); // 异步写入[^4] // 提交保存请求 await mediaLibrary.applyChanges(mediaRequest); } ``` --- ### 三、关键优化点 1. **内存管理**:建议使用`LruCache`缓存最近5秒的帧数据,防止内存溢出 2. **异步处理**:通过`Promise`链式调用确保操作顺序 ```typescript animateTo({}, async () => { await this.captureFrames(); await this.encodeAnimation(); await this.saveToGallery(); }); ``` 3. **分辨率适配**:根据设备屏幕密度自动调整捕获分辨率 ```typescript const display = display.getDefaultDisplaySync(); const captureWidth = display.width * display.densityDPI; ``` --- ### 四、注意事项 1. 动态图片生成需在**UI线程之外**执行 2. 建议添加进度提示组件 3. 不同设备对动态格式支持存在差异,需做兼容检测 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值