QML for Android 加载图片资源的几种方式

前言

前段时间用 QML 做一个简单的 android 程序,需要打开 android手机本地图片,原本是一个非常简单的功能,但是碰到一些坑着实的被坑了一把,然而在网上并没有找到相关的文档,这里做个总结,今后遇到同样问题的人可以绕开这个坑。

正文

打开本地文件

首先来看一下打开本地图片的方式,来看个简单的示例:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Image {
        id: name
        anchors.fill: parent
        source: "file:///storage/emulated/0/Download/1.png"
    }
}

这个程序够简单的了吧,需要注意的是,打开本地图片,需要在路径前面添加“file:///”,不能直接写路径
然后,编译->运行,确保该目录下有这张图片。

然而我遇到的坑就在这里,无论如何都无法显示这张图片,
直接报错:

QML Image: Error decoding: file:///storage/emulated/0/Download/1.png: Unable to read image data

我特么一度在怀疑自己这种写法是不是有问题,然后各种查资料,就是找不到问题所在。
就在一筹莫展的时候,灵机一转,换了张图片,发现特么的竟然可以了,这就让我一脸懵逼了,怎么都没想到竟然是图片的问题,可这张图片明明在本地是可以打开的啊,图片是在其他客户端截图上传并在本机通过 http 从服务器下载的 png 格式,反正就是无法加载到 QML 中使用。好在问题解决了,换成了 重新下载jpg 格式的图片就没问题。最终还是把锅推给这张图片了。

OK,接下来看其他两种更简单的加载图片方式;

打开资源文件

我想这种方式应该是最常见的了,将图片放到资源文件中,然后在代码中进行引用。示例如下:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Image {
        id: name
        anchors.fill: parent
       source: "qrc:/skin/1.jpg"
    }
}

与第一种方式不同的是,引用资源文件时时以“qrc:/”开头。这种方式最常用。

打开 asserts 目录下的文件

Android原生开发中的资源文件大致分为两种,一种是res目录下存放的可编译的资源文件,另一种是 asserts 目录下的用来存放原生的资源图片,系统在编译的时候不会编译assets下的资源文件,在用 Qt 做 Android 开发的时候,如果不想将图片放到 Resource 资源文件中进行编译,那就可以放到 asserts 目录下去。
引用方式如下:

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Image {
        id: name
        anchors.fill: parent
       source:"assets:/skin/1.png"
    }
}

要想引用 assets 中的资源,先要将图片资源放到该目录下去,在 Qt 的工程文件 pro 中添加:

    imgs.files +=/skin/*
    imgs.path = /assets/skin
    INSTALLS += imgs

总结

上面说了三种在 Qt for Android 开发的时候加载图片资源的几种方式,其实每种方式的应用场景都不太一样,所以在开发过程中都有可能会遇到。

其中第一种方式,通常针对引用 Android 手机本地已经存在的图片,比如要做相片浏览功能,这就是打开本地图片,只能用file:///的方式来引用。

第二种和第三种方法,通常针对软件中的一些图标资源引用,比如说某个按钮的图片,区别就是第二种是在编译的是直接将图片打包进安装文件中,这就和 android 原生开发中的资源 res 一样,而第三种方式在编译的时候不会编译资源文件,所以解压安装包后可以直接找到该目录下包含的图标。

OK,至此介绍完了三种方法,如果在引用的时候出现无法加载的情况,首先检查调用方式是否正确,其次看路径是否正确,如果都没问题,不妨换一张图片,有可能是图片的问题。

QML 3D场景可以通过两种方式进行加载: 1. 直接在QML文件中定义场景。这种方式适用于简单的场景,可以通过使用QML的3D元素(如 Box、Sphere、Cylinder 等)来创建3D模型和场景。 例如,以下代码创建了一个简单的场景,其中包含一个盒子和一个球体: ``` import Qt3D.Core 2.12 import Qt3D.Render 2.12 import Qt3D.Extras 2.12 Entity { id: rootEntity components: [ RenderSettings { activeFrameGraph: ForwardRenderer { clearColor: "transparent" } }, Camera { id: camera projectionType: CameraLens.PerspectiveProjection fieldOfView: 45 aspectRatio: 16/9 nearPlane : 0.1 farPlane : 1000.0 position: Qt.vector3d(0.0, 0.0, 40.0) upVector: Qt.vector3d(0.0, 1.0, 0.0) viewCenter: Qt.vector3d(0.0, 0.0, 0.0) } ] BoxMesh { id: boxMesh width: 5.0 height: 5.0 depth: 5.0 } SphereMesh { id: sphereMesh radius: 2.0 } Transform { id: boxTransform translation: Qt.vector3d(-10.0, 0.0, 0.0) } Transform { id: sphereTransform translation: Qt.vector3d(10.0, 0.0, 0.0) } Material { id: material effect: PhongMaterial { ambient: Qt.rgba(0.1, 0.1, 0.1, 1.0) diffuse: Qt.rgba(1.0, 1.0, 1.0, 1.0) specular: Qt.rgba(0.3, 0.3, 0.3, 1.0) shininess: 100.0 } } PhongMaterial { id: material2 ambient: Qt.rgba(0.1, 0.1, 0.1, 1.0) diffuse: Qt.rgba(1.0, 1.0, 1.0, 1.0) specular: Qt.rgba(0.3, 0.3, 0.3, 1.0) shininess: 100.0 } Entity { id: boxEntity components: [ boxMesh, material, boxTransform ] } Entity { id: sphereEntity components: [ sphereMesh, material2, sphereTransform ] } } ``` 2. 通过使用Qt3DSceneLoader加载外部3D模型文件。这种方式适用于复杂的场景,可以使用专业的3D建模软件(如Blender、Maya等)创建模型和场景,并将其导出为支持Qt3D的格式(如.gltf、.obj等)。 例如,以下代码使用Qt3DSceneLoader加载一个外部的.gltf文件: ``` import Qt3D.Core 2.12 import Qt3D.Render 2.12 import Qt3D.Extras 2.12 Entity { id: rootEntity components: [ RenderSettings { activeFrameGraph: ForwardRenderer { clearColor: "transparent" } }, Camera { id: camera projectionType: CameraLens.PerspectiveProjection fieldOfView: 45 aspectRatio: 16/9 nearPlane : 0.1 farPlane : 1000.0 position: Qt.vector3d(0.0, 0.0, 40.0) upVector: Qt.vector3d(0.0, 1.0, 0.0) viewCenter: Qt.vector3d(0.0, 0.0, 0.0) } ] Entity { id: externalEntity Qt3DSceneLoader { id: loader source: "path/to/external/file.gltf" } onStatusChanged: { if (loader.status === Qt3DRender.Qt3DRender.Loaded) { rootEntity.addComponent(externalEntity) } } } } ``` 以上是两种加载QML 3D场景的方式,您可以根据自己的需求进行选择。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luoyayun361

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值