HarmonyOS 鸿蒙Next 切图之后保存为图片文件,开发应可通过id获取资源,但目前无法获取id 图标库

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

HarmonyOS 鸿蒙Next 切图之后保存为图片文件,开发应可通过id获取资源,但目前无法获取id 图标库

切图之后,保存为图片文件,开发应该可以通过id拿到资源,但是现在没办法拿到id 图标库:https://developer.huawei.com/consumer/cn/doc/design-guides/system-icons-0000001929854962#section161242864516


更多关于HarmonyOS 鸿蒙Next 切图之后保存为图片文件,开发应可通过id获取资源,但目前无法获取id 图标库的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

参考下这个demo:

import { common } from '@kit.AbilityKit';
import { BusinessError, request } from '@kit.BasicServicesKit';
import fs from '@ohos.file.fs';
import { fileUri } from '@kit.CoreFileKit';
import { joinPicture } from '../../utils/JoinPicture'
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { image } from '@kit.ImageKit';

@Entry @Component struct Index { @State imageUri: string = ‘’; @State combineImageUri: string = ‘’; context = getContext(this) as common.UIAbilityContext; filePath = this.context.filesDir + ‘/test.jpg’; combinePath = this.context.filesDir + ‘/combine.jpg’; saveButtonOptions: SaveButtonOptions = { icon: SaveIconStyle.FULL_FILLED, text: SaveDescription.SAVE_IMAGE, buttonType: ButtonType.Capsule } // 设置安全控件按钮属性

onPageShow(): void { this.checkImageExist() }

checkImageExist(notExistCallback?: Function) { fs.access(this.filePath).then((res: boolean) => { if (res) { console.info(“PictureJoinTogether file exists”); this.imageUri = fileUri.getUriFromPath(this.filePath); } else { console.info(“PictureJoinTogether file not exists”); if (notExistCallback) { notExistCallback() } } }).catch((err: BusinessError) => { console.info("PictureJoinTogether access failed with error message: " + err.message + ", error code: " + err.code); }); }

// 只是为了分享图片,随便找个图片下载 downloadFile(callback: Function) { this.checkImageExist(() => { request.downloadFile(this.context, { url: https://image.baidu.com/search/down?tn=download&word=download&ie=utf8&fr=detail&url=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F2019-11-22%2F5dd7afa7df0fc.jpg&thumburl=https%3A%2F%2Fimg1.baidu.com%2Fit%2Fu%3D2205810988%2C4283060315%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG%3Fw%3D800%26h%3D500, filePath: this.filePath, background: true }).then((downloadTask: request.DownloadTask) => { downloadTask.on(‘progress’, (receivedSize: number, totalSize: number) => { console.info(“PictureJoinTogether download receivedSize:” + receivedSize + " totalSize:" + totalSize); });

    downloadTask.on(<span class="hljs-string">'complete'</span>, () =&gt; {
      console.info(<span class="hljs-string">'PictureJoinTogether download complete'</span>);
      callback()
    })
  }).catch((err: BusinessError) =&gt; {
    console.error(`PictureJoinTogether Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`);
  });
})

}

build() { Column({space: 10}) { Button(‘下载图片’) .onClick(() => { if (this.imageUri !== ‘’) { return; } this.downloadFile(() => { this.imageUri = fileUri.getUriFromPath(this.filePath); }) })

  Image(<span class="hljs-keyword">this</span>.imageUri)
    .width(<span class="hljs-number">200</span>)
    .height(<span class="hljs-number">200</span>)
    .backgroundColor(Color.Gray)

  Button(<span class="hljs-string">'合并图片并保存到应用内'</span>)
    .onClick(() =&gt; {
      joinPicture.join([<span class="hljs-keyword">this</span>.filePath, <span class="hljs-keyword">this</span>.filePath], <span class="hljs-keyword">this</span>.combinePath, () =&gt; {
        <span class="hljs-keyword">this</span>.combineImageUri = fileUri.getUriFromPath(<span class="hljs-keyword">this</span>.combinePath);
      })
    })

  Image(<span class="hljs-keyword">this</span>.combineImageUri)
    .width(<span class="hljs-number">400</span>)
    .height(<span class="hljs-number">200</span>)
    .backgroundColor(Color.Gray)

  <span class="hljs-comment">// 通过安全控件保存应用图片到图库</span>
  SaveButton(<span class="hljs-keyword">this</span>.saveButtonOptions)
    .onClick(async (event, result: SaveButtonOnClickResult) =&gt; {
      <span class="hljs-keyword">if</span> (result === SaveButtonOnClickResult.SUCCESS) {
        <span class="hljs-keyword">try</span> {
          <span class="hljs-keyword">const</span> context = getContext();
          <span class="hljs-keyword">const</span> phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
          <span class="hljs-keyword">const</span> uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, <span class="hljs-string">'jpg'</span>);
          console.info(<span class="hljs-string">'createAsset successfully, uri: '</span> + uri);
          <span class="hljs-keyword">const</span> file = await fs.open(uri, fs.OpenMode.READ_WRITE);
          <span class="hljs-keyword">const</span> imageSource = image.createImageSource(<span class="hljs-keyword">this</span>.combinePath);
          <span class="hljs-keyword">const</span> imageInfo = await imageSource.getImageInfo();
          <span class="hljs-keyword">const</span> opts: image.DecodingOptions = {
            editable: <span class="hljs-literal">true</span>,
            <span class="hljs-comment">// 注意和拼接图片时的格式统一</span>
            desiredPixelFormat: image.PixelMapFormat.BGRA_8888,
            desiredSize: { width: imageInfo.size.width, height: imageInfo.size.height }
          };
          <span class="hljs-comment">// 需要通过packing打包图片,直接获取buffer并写入会导致图库中图片无法显示</span>
          <span class="hljs-keyword">const</span> pixelMap = await imageSource.createPixelMap(opts);
          <span class="hljs-keyword">const</span> imagePackerApi: image.ImagePacker = image.createImagePacker();
          <span class="hljs-keyword">let</span> packOpts: image.PackingOption = { format: <span class="hljs-string">"image/jpeg"</span>, quality: <span class="hljs-number">100</span> };
          <span class="hljs-keyword">const</span> packingArrayBuffer = await imagePackerApi.packing(pixelMap, packOpts);
          console.info(<span class="hljs-string">'packing succeeded.'</span>);
          fs.writeSync(file.fd, packingArrayBuffer, { offset: <span class="hljs-number">0</span> })
          fs.closeSync(file.fd)
        } <span class="hljs-keyword">catch</span> (err) {
          console.error(<span class="hljs-string">'createAsset failed, message = '</span>, err);
        }
      } <span class="hljs-keyword">else</span> {
        console.error(<span class="hljs-string">'SaveButtonOnClickResult createAsset failed'</span>);
      }
    })
}
.width(<span class="hljs-string">'100%'</span>)
.height(<span class="hljs-string">'100%'</span>)
.justifyContent(FlexAlign.Center)

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

import { image } from ‘@kit.ImageKit’;
import fs from ‘@ohos.file.fs’;

class JoinPicture { /**

  • RGBA与BGRA编码互换,前后统一编码后,就不需要转换了
  • @param data
  • @returns */ rgba2BGRA(data: ArrayBuffer): ArrayBuffer { let length: number = data.byteLength; let tempBuffer: ArrayBuffer = new ArrayBuffer(length); let rgbaData = new DataView(data); let bgraData = new DataView(tempBuffer); for (let i = 0; i < length; i += 4) { bgraData.setUint8(i, rgbaData.getUint8(i + 2)); bgraData.setUint8(i + 1, rgbaData.getUint8(i + 1)); bgraData.setUint8(i + 2, rgbaData.getUint8(i)); bgraData.setUint8(i + 3, rgbaData.getUint8(i + 3)); } return bgraData.buffer }

// 这里只考虑横向排列拼接,且每张小图的高度一致 async join(picturePaths: Array<string>, joinPath: string, callback: Function) { try { if (picturePaths.length < 2) { console.info(‘PictureJoinTogether 需要拼接的图片数量不足’) return; } const tempPath = picturePaths[0]; const imageSource = image.createImageSource(tempPath); const imageInfo = await imageSource.getImageInfo(); const singleWidth = imageInfo.size.width; const singleHeight = imageInfo.size.height;

  <span class="hljs-keyword">const</span> combineOpts: image.InitializationOptions = {
    alphaType: <span class="hljs-number">0</span>,
    editable: <span class="hljs-literal">true</span>,
    <span class="hljs-comment">// 注意上下格式统一</span>
    pixelFormat: image.PixelMapFormat.BGRA_8888,
    size: { width: singleWidth * picturePaths.length, height: singleHeight }
  }
  <span class="hljs-keyword">const</span> singleOpts: image.DecodingOptions = {
    editable: <span class="hljs-literal">true</span>,
    desiredPixelFormat: image.PixelMapFormat.BGRA_8888,
    desiredSize: { width: singleWidth, height: singleHeight }
  };
  <span class="hljs-keyword">const</span> combineColor = <span class="hljs-keyword">new</span> <span class="hljs-built_in">ArrayBuffer</span>(combineOpts.size.width * combineOpts.size.height * <span class="hljs-number">4</span>);
  <span class="hljs-keyword">let</span> singleColor = <span class="hljs-keyword">new</span> <span class="hljs-built_in">ArrayBuffer</span>(singleOpts.desiredSize!.width * singleOpts.desiredSize!.height * <span class="hljs-number">4</span>);
  <span class="hljs-keyword">const</span> newPixelMap = await image.createPixelMap(combineColor, combineOpts);
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> x = <span class="hljs-number">0</span>; x &lt; picturePaths.length; x++) {
    <span class="hljs-comment">//读取小图</span>
    <span class="hljs-comment">//图片应用沙箱路径</span>
    <span class="hljs-keyword">let</span> singlePath = picturePaths[x];
    <span class="hljs-keyword">let</span> imageSource = image.createImageSource(singlePath);
    <span class="hljs-keyword">const</span> singlePixelMap = await imageSource.createPixelMap(singleOpts);
    await singlePixelMap.readPixelsToBuffer(singleColor);
    <span class="hljs-comment">//写入大图</span>
    <span class="hljs-keyword">let</span> area: image.PositionArea = {
      pixels: singleColor,
      offset: <span class="hljs-number">0</span>,
      stride: singleWidth * <span class="hljs-number">4</span>,
      region: {
        size: { height: singleHeight, width: singleWidth },
        x: singleWidth * x,
        y: <span class="hljs-number">0</span>
      }
    }
    await newPixelMap.writePixels(area);
  }
  <span class="hljs-keyword">let</span> combinePixelMap = newPixelMap;
  <span class="hljs-comment">//保存大图</span>
  <span class="hljs-keyword">const</span> saveResult = await <span class="hljs-keyword">this</span>.save(combinePixelMap, joinPath)
  saveResult &amp;&amp; callback();
} <span class="hljs-keyword">catch</span> (err) {
  console.error(<span class="hljs-string">'PictureJoinTogether join error: '</span> + <span class="hljs-built_in">JSON</span>.stringify(err))
}

}

async save(pixelMap: image.PixelMap | undefined, path: string) { if (pixelMap === undefined) { return false; } const imagePackerApi: image.ImagePacker = image.createImagePacker(); let packOpts: image.PackingOption = { format: “image/jpeg”, quality: 100 }; const packingArrayBuffer = await imagePackerApi.packing(pixelMap, packOpts); console.info(‘packing succeeded.’); let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); fs.writeSync(file.fd, packingArrayBuffer, { offset: 0 }) fs.closeSync(file.fd) return true } }

export const joinPicture = new JoinPicture()<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>

更多关于HarmonyOS 鸿蒙Next 切图之后保存为图片文件,开发应可通过id获取资源,但目前无法获取id 图标库的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙系统中,对于Next切图后保存为图片文件并通过ID获取资源的问题,首先需要确认几个关键点以确保流程无误。

  1. 资源文件路径与命名:确保切图后的图片资源已正确导入项目资源文件夹,且文件名(包括扩展名)与在代码中引用的ID完全匹配。HarmonyOS对资源命名有严格要求,通常使用小写字母、数字和下划线。

  2. 资源ID定义:检查资源文件是否在项目的资源定义文件(如resources.json或对应XML文件)中正确声明了ID,并且ID的命名遵循系统规则,无重复且格式正确。

  3. 代码引用:在代码中获取资源时,确保使用的ID与资源文件中定义的完全一致。通常通过资源管理系统(如ResourceManager)来获取资源。

  4. 编译与清理:尝试清理并重新编译项目,有时候IDE缓存或编译过程中的问题可能导致资源无法正确加载。

  5. 权限检查:确认应用是否具有访问存储资源(如读写外部存储)的权限,特别是如果资源文件存储在特定路径下。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。

回到顶部