Search code examples
imageqtqmltexture-atlas

Image atlas in QML


I have an image like this one: http://www.imagemagick.org/Usage/basics/result.gif (it contains two rows of individual data: three square images in the upper row, and below another square and two 'empty' squares)

I want to use it inside a repeater, so that I get four image buttons, each with one of the subimages.

Is there a "texture-atlas" modules in QML?

I only found http://doc.qt.io/qt-5/qml-qtquick-sprite.html and I hope there is something that is better for my use-case.


Solution

  • As I said in comment I would do that using QQuickImageProvider since that's the fastest and the least memory intensive way. But QML is very flexible and you can do with it whatever you want. As for your question you can do as following:

    Tile.qml

    import QtQuick 2.9
    
    Item {
        id: container
        property alias source: img.source
        property int cellWidth: 1
        property int cellHeight: 1
        property int slideIndex: 0
        clip: true
        Image {
            id: img
            property int cols: img.paintedWidth / container.cellWidth
            property int rows: img.paintedHeight / container.cellHeight
            x: -container.cellWidth * Math.floor(container.slideIndex % cols)
            y: -container.cellHeight * Math.floor(container.slideIndex / cols)
        }
    }
    

    and usage:

    import QtQuick 2.9
    import QtQuick.Window 2.2
    
    Window {
        id: window
        title: "Test"
        visible: true
        width: 600
        height: 400
    
        Row {
            spacing: 10
            anchors.centerIn: parent
            Repeater {
                model: 4
                Tile {
                    width: 32
                    height: 32
                    cellWidth: 32
                    cellHeight: 32
                    slideIndex: index
                    source: "http://www.imagemagick.org/Usage/basics/result.gif"
                }
            }
        }
    }
    

    The idea is to wrap the entire image into a container and clip it appropriately. Here I use index-based access to a slide, you can do that as you want.