HarmonyOS 鸿蒙Next ArkUI中加载网络图片的问题

HarmonyOS 鸿蒙Next ArkUI中加载网络图片的问题

参考这位老兄的提问,我也遇到的相同的问题。

根据官方提供Image组件加载网络图片的代码:

// 先创建一个PixelMap状态变量用于接收网络图片  
@State image: PixelMap = undefined  
build() {  
  Column({space: 10}) {  
    Button("获取网络图片")  
      .onClick(() => {  
        this.httpRequest();  
      })  
    Image(this.image).height(100).width(100)  
  }  
  .width('100%')  
  .height('100%')  
  .padding(10)  
}  
// 网络图片请求方法  
private httpRequest() {  
  let httpRequest = http.createHttp();      
  httpRequest.request(  
    "https://www.example.com/xxx.png",   // 请填写一个具体的网络图片地址  
    (error, data) => {  
      if(error) {  
        console.log("error code: " + error.code + ", msg: " + error.message)  
      } else {  
        let code = data.responseCode          
        if(ResponseCode.ResponseCode.OK == code) {  
          let imageSource = image.createImageSource(data.result)  
          let options = {alphaType: 0,                     
                         editable: false,                  
                         pixelFormat: 3,                   
                         scaleMode: 1,                     
                         size: {height: 100, width: 100}}  
          imageSource.createPixelMap(options).then((pixelMap) => {  
            this.image = pixelMap  
          })  
        } else {  
          console.log("response code: " + code);  
        }  
      }  
    }  
  )  
}

发现但这段代码有个问题:

let imageSource = image.createImageSource(data.result)

使用API8,这个createImageSource方法的提示是要传入一个url:string,但其实http直接访问图片网址,请求到的data.result是这样的

如果直接在控制台打印data.result as string,是可以看到和图上TEXT相同的乱码文本的。但这个文本显然是Image组件无法直接使用的

因此我又查看了giee上官方提供的图片处理相关API

https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-image.md#imagecreatepixelmap8

按照我的理解,核心逻辑是要构建一个 pixelMap,Image组件直接绑定该 pixelMap,然后把请求到的图像数据写入 pixelMap 中。

写了一段,还是没跑通,代码如下:

这张网络图片的一些属性如下:

图片大小66.5 KB

网络请求返回的Content-Length=68107

分辨率 1125x750

struct Index {  
  // 先创建一个PixelMap状态变量用于接收网络图片  
  @State imageMy: PixelMap = undefined  
  build() {  
    Column({ space: 10 }) {  
      Button("获取网络图片")  
        .onClick(() => {  
          this.httpRequest();  
        })  
      Image(this.image)  
        .height(100)  
        .width(100)  
        .alt($r('app.media.ic_launcher'))  
        .objectFit(ImageFit.Contain)  
    }  
    .width('100%')  
    .height('100%')  
    .padding(10)  
  }  
  // 网络图片请求方法  
  private httpRequest() {  
    let httpRequest = http.createHttp();  
    httpRequest.request(  
      "https://images.pexels.com/photos/7858743/pexels-photo-7858743.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1", // 请填写一个具体的网络图片地址  
      {  
        method: http.RequestMethod.GET, // 可选,默认为http.RequestMethod.GET  
        // 开发者根据自身业务需要添加header字段  
        header: {},  
        connectTimeout: 60000, // 可选,默认为60s  
        readTimeout: 60000, // 可选,默认为60s  
      },  
      (error, data) => {  
        if (error) {  
          console.log("error code: " + error.code + ", msg: " + error.message)  
        } else {  
          // data.header为http响应头,可根据业务需要进行解析  
          console.info('header:' + JSON.stringify(data.header));  
          let code = data.responseCode          
          if (ResponseCode.ResponseCode.OK == code) {  
            console.info("ResponseCode.ResponseCode.OK=" + ResponseCode.ResponseCode.OK)  
            console.info("code=" + ResponseCode.ResponseCode.OK)  
            let resultArrayBuffer = data.result as ArrayBuffer  
            let resultArrayBufferLength = new ArrayBuffer(3375000)  
            console.info("resultArrayBuffer=" + resultArrayBuffer.length)  
            let options = {  
              alphaType: 0, // 透明度  
              editable: true, // 是否可编辑  
              pixelFormat: 2, // 像素格式  
              scaleMode: 1, // 缩略值  
              size: { height: 750, width: 1125 }  
            } // 创建图片大小  
            image.createPixelMap(resultArrayBufferLength, options).then((pixelMap) => {  
              pixelMap.writeBufferToPixels(resultArrayBuffer).then(() => {  
                console.log("Succeeded in writing data from a buffer to a PixelMap.");  
                this.imageMy=pixelMap  
              }).catch((err) => {  
                console.error("Failed to write data from a buffer to a PixelMap."+err);  
              })  
            })  
          } else {  
            console.log("response code: " + code);  
          }  
        }  
      }  
    )  
  }

关键点有几个:

  1. createPixelMap函数第一个参数需要接收一个ArrayBuffer,最开始我以为这个地方可以直接传入data.result as ArrayBuffer这种形式,发现会提示错误。
  2. 于是手动确定图片大小后,按照 上述图片处理API 所述,根据图片分辨率1125x720x4创建了ArrayBuffer;
  3. createPixelMap第二个参数options中的 size: { height: 750, width: 1125 }
  4. 使用writeBufferToPixels方法将传入的data.result as ArrayBuffer写入pixelMap中。

一切看起来好像没问题,看日志似乎createPixelMap也成功了,但一个报错又给我整不会了。

Failed to write data from a buffer to a PixelMap.Error: Failed to napi_get_arraybuffer_info!


更多关于HarmonyOS 鸿蒙Next ArkUI中加载网络图片的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

11 回复
let resultArrayBuffer = data.result as ArrayBuffer

let options = {
  alphaType: 0, // 透明度
  editable: true, // 是否可编辑
  pixelFormat: 2, // 像素格式
  scaleMode: 1, // 缩略值
  size: { height: 750, width: 1125 }
} // 创建图片大小
const imageSource = image.createImageSource(resultArrayBuffer);
imageSource.createPixelMap(options).then(pixelMap=>{
  console.log("Succeeded in getting a PixelMap.");
  this.imageMy=pixelMap;
  // 获取图片大小
  pixelMap.getImageInfo().then( info => {
    console.info('info.width = ' + info.size.width);
    console.info('info.height = ' + info.size.height);
  }).catch(err => {
    console.error("Failed to obtain the image pixel map information.And the error is: " + err);
  });
});

我用的HarmonyOS Sdk 3.1.0(API 9)

更多关于HarmonyOS 鸿蒙Next ArkUI中加载网络图片的问题的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


谢谢大佬,这个问题我后来测试过在api9里确实已经被解决了,虽然现在才看到你回复但还是先采纳你的回答,让这个求助帖圆满。

请问解决了吗

开发者您好,经rk最新版本验证可以获取网络图片。相关文档地址:https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/arkui-ts/ts-basic-components-image.md#网络图片

这需要API 9的SDK和API 9的设备才支持么,我目前使用的是Harmony的SDK,并没有使用OpenHarmony的。

开发者您好,图片上传下载可以参考以下示例:https://gitee.com/openharmony/app_samples/tree/master/Network/UploadDownload

我要做的不是下载呀,就是正常请求图片网址,并通过Image组件加载而已。不需要真正的下载到本地成为文件,

您好,请看下3最新的回复哦~

找HarmonyOS工作还需要会Flutter技术的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:BV1S4411E7LY/?p=17

麻烦各位大佬和版主大大指点一下!卡在这很久了

在HarmonyOS鸿蒙系统的Next ArkUI中加载网络图片,可以通过使用Image组件并设置其src属性为网络图片的URL来实现。为了确保图片能够正确加载,通常需要考虑到网络请求权限、图片URL的有效性以及组件的状态管理。

具体步骤如下:

  1. 确保网络权限:在config.json文件中添加网络权限配置,允许应用访问网络。

  2. 使用Image组件:在ArkUI的页面布局中,使用Image组件来展示图片。通过绑定数据的方式,将图片的URL传递给Image组件的src属性。

  3. 处理图片加载状态:可以通过监听Image组件的加载事件来处理图片加载成功、失败或加载中等状态,从而给用户更好的体验。

  4. 考虑性能优化:对于大量图片加载的场景,可以考虑使用图片懒加载、缓存等技术来优化性能。

示例代码(伪代码):

@Entry
@Component
struct MyComponent {
    @State private imageUrl: string = 'https://example.com/image.jpg';

    build() {
        Image($imageUrl)
            .onLoad(() => {
                // 图片加载成功处理
            })
            .onError(() => {
                // 图片加载失败处理
            });
    }
}

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

回到顶部