HarmonyOS 鸿蒙Next 如何解决Canvas组件下设置drawImage图片没有展示的问题

发布于 1周前 作者 eggper 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 如何解决Canvas组件下设置drawImage图片没有展示的问题

如何解决Canvas组件下设置drawImage图片没有展示的问题

【问题现象】

有三张图片分别命名icon1、icon2、icon3,随机数随机生成中的某一个数,找到相应的图片,Canvas使用drawImage无法绘制出来。运行结果如下:

问题代码如下:

private drawImage() {
    // 获取1-3随机数
    let random: number = RandomUtil.randomNumber(1, 3)
    this.bgViweName = `app.media.icon${random}`
    ...
    const context: Context = getContext(this);
    const resourceManager: resourceManager.ResourceManager = context.resourceManager;

    resourceManager.getMediaContent($r(this.bgViweName)).then((data: Uint8Array) => {
      const buffer = data.buffer.slice(0);
      const imageSource: image.ImageSource = image.createImageSource(buffer);
      let decodingOptions: image.DecodingOptions = {
        editable: true,
        desiredPixelFormat: 3,
      }
      imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
        this.img = new ImageBitmap(pixelMap);
        // 绘制image
        this.drawContext.drawImage(this.img, 0, 0, PuzzleSize, PuzzleSize + BezierOffset)
      }).catch((err: BusinessError) => {
        console.error("create PixelMap error: " + err.toString())
      });
    }).catch((err: BusinessError) => {
      console.error("getMediaContent error: " + err.toString())
    })
  }

【背景知识】

1、Canvas画布组件

画布组件可用于用于自定义绘制图形。

2、资源管理模块提供获取应用资源信息读取接口

其中getMediaByName接口可以获取指定资源名称对应的媒体文件内容,getMediaContent接口可以获取指定资源ID对应的媒体文件内容。

3、在工程中,可以通过"$r('app.type.name')"的形式引用应用资源

app代表是应用内resources目录中定义的资源;type 代表资源类型(或资源的存放位置),可以取 color、float、string、plural和media,name代表资源命名。

【定位思路】

(1)首先检查了随机数生成的图片名称是正确的,执行的过程也没报异常。

(2)注释掉其他代码,传入固定的名称的图片,发现图片可以正常加载。

resourceManager.getMediaContent($r('app.media.icon1')).then((data:
  const buffer = data.buffer.slice(0);
  const imageSource: image.ImageSource = image.createImageSource(buffer);
  let decodingOptions: image.DecodingOptions = {
    editable: true,
    desiredPixelFormat: 3,
  }
  imageSource.createPixelMap(decodingOptions).then((pixelMap: image.PixelMap) => {
    this.img = new ImageBitmap(pixelMap);
    // 绘制image
    this.moveContext.drawImage(this.img, 0, 0, PuzzleSize, PuzzleSize + BezierOffset)
  }).catch((err: BusinessError) => {
    console.error("create PixelMap error: " + err.toString())
  });
}).catch((err: BusinessError) => {
  console.error("getMediaContent error: " + err.toString())
})

(3)因此确认了是$r传的参数问题:如果传入的是一个字符串变量,则加载不出来。

【解决方案】

方案一:使用getMediaByName替换原来的getMediaContent方法

getMediaByName的参数是字符串,因此可用于getMediaContent。

代码示例如下:

private drawImage() {
  // 获取1-3随机数
  let random: number = RandomUtil.randomNumber(1, 3);
  // 传参是名称即可,不用加app.media
  this.bgViweName = `icon${random}`
  ...

  const context: Context = getContext(this);
  const resourceManager: resourceManager.ResourceManager = context.resourceManager;

  resourceManager.getMediaByName(this.bgViweName).then((data: Uint8Array) => {
    ...
  }).catch((err: BusinessError) => {
    console.error("create PixelMap error: " + err.toString())
  });
}).catch((err: BusinessError) => {
  console.error("getMediaContent error: " + err.toString())
})

方案二:用map将图片名称和Resource建立关联

建立一个名字和Resource的map映射,从map中取出随机数生成的名称对应的Resource,传入getMediaContent方法。

代码示例如下:

// 将名称转换成resource
let viewResource = this.map.get(this.bgViweName);
resourceManager.getMediaContent(viewResource).then((data: Uint8Array) => {
  ...
}).catch((err: BusinessError) => {
  console.error("getMediaContent error: " + err.toString())
})

修改后效果:

【总结】

使用 $r获取Resource可以使代码更加简洁方便,但需要注意的是:虽然$r传入的参数类型是字符型的,但是由于它是在编译时处理,不支持程序运行时动态改变,因此不能传入变量。如果想要实现动态改变的要求,可以尝试在resourceManager里找到相应的方法进行替换。

1 回复

作为IT专家,对于HarmonyOS 鸿蒙Next在Canvas组件下设置drawImage图片没有展示的问题,这里提供一些可能的解决方案:

首先,确认图片路径是否正确,并确保图片文件存在于指定路径中。同时,检查图片格式是否为Canvas组件所支持,例如PNG、JPEG等常用格式。如果图片格式不被支持,可能会导致图片无法正常显示。

其次,如果图片是从网络加载的,需要确保已添加网络权限,并检查网络连接是否正常。网络问题可能导致图片加载失败,从而无法在Canvas上显示。

另外,还需要检查Canvas组件的绘制代码是否正确。确保在绘制图片前,Canvas的上下文(context)已经正确创建,并且drawImage方法被正确调用。如果绘制代码有误,可能导致图片无法正常绘制到Canvas上。

最后,如果以上方法都无法解决问题,可能是Canvas组件或drawImage方法本身存在bug。此时,可以尝试更新HarmonyOS的版本,或者查看鸿蒙开发者社区的相关讨论,看是否有其他开发者遇到并解决了类似的问题。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。他们将能够提供更专业的技术支持和帮助。

回到顶部