HarmonyOS鸿蒙Next中如何将staticmap保存到本地图库

HarmonyOS鸿蒙Next中如何将staticmap保存到本地图库

async savePixelMapToAlbum() {
  let helper = photoAccessHelper.getPhotoAccessHelper(this.context);
  let uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpeg');
  let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
  let imagePackerApi = image.createImagePacker();
  let packOpts: image.PackingOption = { format: 'image/jpeg', quality: 98 };

  imagePackerApi.packToFile(this.pixel, file.fd, packOpts, (err: BusinessError) => {
    if (err) {
      console.error(`Failed to pack the image to file.code ${err.code},message is ${err.message}`);
    } else {
      console.info('Succeeded in packing the image to file.');
      imagePackerApi.release((err: BusinessError) => {
        if (err) {
          console.error(`Failed to release the image source instance.code ${err.code},message is ${err.message}`);
        } else {
          console.info('Succeeded in releasing the image source instance.');
          fileIo.close(file.fd);
        }
      })
      this.getUIContext().getPromptAction().showToast({ message: '已保存至相册!' });
    }
  })
}

更多关于HarmonyOS鸿蒙Next中如何将staticmap保存到本地图库的实战教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

开发者你好,可以参考下以下示例通过SaveButton进行保存staticmap到图库。

本地示例demo:

import { staticMap } from '@kit.MapKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { image } from '@kit.ImageKit';
import { fileIo } from '@kit.CoreFileKit';

@Entry
@Component
struct Index {
  @State image?: PixelMap = undefined;
  private context: Context = this.getUIContext().getHostContext()!;

  build() {
    Column() {
      this.buildDemoUI();
    }.width('100%')
    .margin({ bottom: 48 })
    .backgroundColor(0xf2f2f2)
    .height('100%');
  }

  @Builder
  buildDemoUI() {
    // 展示获取的静态图
    Image(this.image)
      .width('100%')
      .fitOriginalSize(false)
      .border({ width: 1 })
      .borderStyle(BorderStyle.Dashed)
      .objectFit(ImageFit.Contain)
      .height('80%');

    Column() {
      Button('getStaticMap')
        .fontSize(12)
        .margin({ top: 15 })
        .onClick(async () => {
          // 设置静态图标记参数
          let markers: Array<staticMap.StaticMapMarker> = [{
            location: { latitude: 50, longitude: 126.3 },
            font: 'statics',
            defaultIconSize: staticMap.IconSize.TINY
          }];

          // 设置静态图绘制路径参数
          let path: staticMap.StaticMapPath = {
            locations: [
              { latitude: 50, longitude: 126 },
              { latitude: 50.3, longitude: 126 },
              { latitude: 50.3, longitude: 126.3 },
              { latitude: 49.7, longitude: 126 },
              { latitude: 50, longitude: 126 }
            ],
            width: 3
          };

          // 拼装静态图参数
          let option: staticMap.StaticMapOptions = {
            location: { latitude: 50, longitude: 126 },
            zoom: 10,
            imageWidth: 1024,
            imageHeight: 1024,
            scale: 1,
            markers: markers,
            path: path
          };

          try {
            // 获取静态图
            this.image = await staticMap.getMapImage(option);
            console.info('Succeeded in getting image.');
          } catch (error) {
            const err: BusinessError = error as BusinessError;
            console.error(`Failed in getting image, code: ${err.code}, message: ${err.message}`);
          }
        });

      SaveButton()
        .fontSize(12)
        .onClick(async () => {
          if (this.image) {
            saveToFile(this.image,this.context)
          }
        });
    };
  }
}

export async function saveToFile(pixelMap: image.PixelMap, context: Context): Promise<void> {
  let fd: number | null = null;
  try {
    let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
    let filePath = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png');
    let imagePacker = image.createImagePacker();
    let imageBuffer = await imagePacker.packToData(pixelMap, {
      format: 'image/png',
      quality: 100,
      needsPackProperties: true,
    });
    let mode = fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE;
    fd = (await fileIo.open(filePath, mode)).fd;
    await fileIo.truncate(fd);
    await fileIo.write(fd, imageBuffer);
  } catch (err) {
    console.error('saveToFile error:', JSON.stringify(err) ?? '');
  } finally {
    if (fd) {
      fileIo.close(fd);
    }
  }
}

【背景知识】

  • SaveButton组件。 SaveButton允许用户通过点击按钮临时获取存储权限,无需额外的编写权限申请代码。当用户点击该控件时,应用会获得一分钟内单次访问媒体库特权接口的授权。这适用于任何需要将文件保存到媒体库的应用场景,例如保存图片或视频等。

更多关于HarmonyOS鸿蒙Next中如何将staticmap保存到本地图库的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


没懂你想要干嘛

在HarmonyOS Next中,将StaticMap保存到本地图库,需要使用媒体库管理能力。首先,通过@ohos.file.fs将StaticMap的位图数据写入应用沙箱路径下的临时文件。然后,使用@ohos.file.photoAccessHelperPhotoAccessHelper接口,将临时文件移动到公共图库目录(如Pictures/)中。操作完成后,系统相册即可显示该图片。整个过程需在应用配置文件中声明必要的存储权限。

在HarmonyOS Next中,将staticmap(通常指地图静态图片)保存到本地图库,核心在于将地图数据转换为PixelMap对象,然后使用您已有的savePixelMapToAlbum方法进行保存。

以下是关键步骤和代码示例:

  1. 获取StaticMap并转换为PixelMap: 假设您通过地图服务(如@ohos.geoLocationManager或第三方地图SDK)获取到了地图的图片数据,可能是ArrayBufferResourcePixelMap格式。您需要将其转换为PixelMap

    import image from '@ohos.multimedia.image';
    
    // 假设 mapData 是获取到的地图图片数据(例如ArrayBuffer)
    async function convertToPixelMap(mapData: ArrayBuffer): Promise<image.PixelMap> {
      try {
        // 创建ImageSource对象
        const imageSource = image.createImageSource(mapData);
        // 解码并获取PixelMap
        const pixelMap = await imageSource.createPixelMap();
        // 释放ImageSource资源
        imageSource.release();
        return pixelMap;
      } catch (error) {
        console.error('Failed to convert map data to PixelMap.', error);
        throw error;
      }
    }
    
  2. 调用保存方法: 在获取到PixelMap后,直接调用您已有的savePixelMapToAlbum方法。

    // 在您的业务逻辑中
    async function saveStaticMapToAlbum() {
      try {
        // 1. 获取地图数据(此处为示例,需替换为实际获取地图数据的代码)
        const mapData: ArrayBuffer = await fetchMapStaticImage(); // 自定义函数,获取地图ArrayBuffer
        // 2. 转换为PixelMap
        const pixelMap = await convertToPixelMap(mapData);
        // 3. 保存到相册(将pixelMap赋值给this.pixel)
        this.pixel = pixelMap;
        await this.savePixelMapToAlbum();
      } catch (error) {
        console.error('Failed to save static map to album.', error);
        // 处理错误,例如提示用户
      }
    }
    

注意事项

  • 权限申请:确保在module.json5中声明了相册访问权限(ohos.permission.READ_IMAGEVIDEOohos.permission.WRITE_IMAGEVIDEO),并在保存前动态申请(API 10+推荐使用userFileManager)。
  • 数据格式:如果地图服务直接返回PixelMap,则无需转换,直接保存即可。
  • 资源释放:在保存完成后,及时释放PixelMap资源(pixelMap.release()),避免内存泄漏。

您提供的savePixelMapToAlbum方法已经实现了将PixelMap编码为JPEG并写入相册的核心逻辑,只需确保传入正确的PixelMap对象即可。

回到顶部