HarmonyOS 鸿蒙Next 如何解决Canvas组件下设置drawImage图片没有展示的问题
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里找到相应的方法进行替换。
作为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 。他们将能够提供更专业的技术支持和帮助。