Python 重新加载QML画布图像

Python 重新加载QML画布图像,python,qml,pyside2,Python,Qml,Pyside2,我正在使用QML画布绘制图像。使用Python、OpenCV和NumPy在后端加载映像,并通过从QQuickImageProvider继承的自定义映像提供程序提供给QML。要在QML中重新加载图像,请执行以下操作: unloadImage('image://<providerName>/<ID>') loadImage('image://<providerName>/<ID>') main.qml import QtQuick 2.0 impor

我正在使用QML画布绘制图像。使用Python、OpenCV和NumPy在后端加载映像,并通过从QQuickImageProvider继承的自定义映像提供程序提供给QML。要在QML中重新加载图像,请执行以下操作:

unloadImage('image://<providerName>/<ID>')
loadImage('image://<providerName>/<ID>')
main.qml

import QtQuick 2.0
import QtQuick.Controls 2.0

ApplicationWindow {
    id: root
    visible: true
    width: 800
    height: 480

    // =============
    // Event Handler
    // =============
    onHeightChanged: {
        imagePainter.resize()
    } 

    onWidthChanged: {
        imagePainter.resize()
    } 

    // ========
    // Children
    // ========
    Item {
        anchors {
            top: parent.top
            bottom: button.top
            right: parent.right
            left: parent.left
            bottomMargin: 10
        }

        Canvas {
            id: imagePainter
            anchors {
                horizontalCenter: parent.horizontalCenter
                verticalCenter: parent.verticalCenter
            }

            // =================
            // Custom Properties
            // =================
            property var size: {
                'width': -1,
                'height': -1
            }
            property real scale: 1
            property var image: 'image://CustProv/image'

            // =========
            // Functions
            // =========
            function resize() {
                console.log("Resizing canvas contents")
                var wToH =  size.width/size.height
                if (parent.width/parent.height >= wToH) {
                    // image aspect ratio is narrower than parent 
                    // aspect ratio: Use full height
                    height = parent.height
                    width = wToH * parent.height
                    scale = height/size.height
                }
                else {    
                    // image aspect ratio is wider than parent 
                    // aspect ratio: use full width   
                    width = parent.width          
                    height = parent.width / wToH
                    scale = width/size.width
                }
                // repaint the image
                requestPaint();
            }

            function reload() {
                console.log("Reload triggered")
                // First, get the new image size
                var imSize = CustProv.getImageSize()
                size.width = imSize[0]
                size.height = imSize[1]
                resize()

                // Reload image
                unloadImage(image) <--- Seems to fail for small images
                loadImage(image)
            }

            // =============
            // Event Handler
            // =============
            Component.onCompleted: {
                console.log("connecting external signals")
                CustProv.updateImage.connect(reload)
            }

            onPaint: {
                // Invoked by requestPaint()
                if (!isImageLoaded(image)) {
                    return
                }
                var ctx = getContext('2d')
                ctx.clearRect(0, 0, width, height)
                ctx.scale(scale, scale)
                ctx.drawImage(image, 0, 0)
                ctx.scale(1/scale, 1/scale)
            }

            onImageLoaded: {
                requestPaint()
            }
        }
    }


    Button {
        id: button
        anchors {
            right: parent.right
            bottom: parent.bottom
            bottomMargin: 10
            rightMargin: 10
        }

        width: 200
        height: 25

        text: "Change Image"

        onClicked: {
            CustProv.changeImage()
        }
    }
}
导入QtQuick 2.0
导入QtQuick.Controls 2.0
应用程序窗口{
id:根
可见:正确
宽度:800
身高:480
// =============
//事件处理程序
// =============
onHeightChanged:{
imagePainter.resize()
} 
onWidthChanged:{
imagePainter.resize()
} 
// ========
//孩子们
// ========
项目{
锚定{
top:parent.top
底部:按钮。顶部
右:家长。对
左:parent.left
底边距:10
}
帆布{
id:imagePainter
锚定{
horizontalCenter:父对象。horizontalCenter
verticalCenter:父级。verticalCenter
}
// =================
//自定义属性
// =================
属性变量大小:{
“宽度”:-1,
“高度”:-1
}
不动产规模:1
属性变量图像:'image://CustProv/image'
// =========
//功能
// =========
函数resize(){
log(“调整画布内容的大小”)
var wToH=size.width/size.height
如果(parent.width/parent.height>=wToH){
//图像纵横比比比父对象窄
//纵横比:使用全高
高度=parent.height
宽度=wToH*parent.height
比例=高度/尺寸.高度
}
否则{
//图像纵横比比比父级宽
//纵横比:使用全宽
宽度=parent.width
高度=父级宽度/wToH
比例=宽度/尺寸.width
}
//重新绘制图像
requestPaint();
}
函数重载(){
日志(“重新加载触发”)
//首先,获取新的图像大小
var imSize=CustProv.getImageSize()
size.width=imSize[0]
size.height=imSize[1]
调整大小()
//重新加载图像
根据以下要求解除图像(图像):

QQuickImageProvider返回的图像会自动缓存,类似于QML引擎加载的任何图像。当从缓存加载带有“image://”前缀的图像时,requestImage()和requestPixmap()会不会为相关图像提供程序调用。如果应始终从图像提供程序提取图像,并且根本不应缓存图像,请将相关图像、BorderImage或AnimateImage对象的cache属性设置为false

因此,您需要将
Image
组件的
cache
属性设置为
false


要重新加载图像,您只需将源路径修改为null并将其还原为以前的值。

谢谢您的快速响应。我使用的是QML画布,而不是QML图像或任何相关类型。我担心画布没有cache属性,因为它们可以包含多个图像。@JanOsch,因此您只需要重新绘制canv作为。最好添加一个最小的代码抱歉。图像都来自:mesi5.jpg有548x342 px,lena.jpg有512x512 pxmm,问题与大小无关,但与画布缓存有关。您的主要目标是什么?@eyllansc:目标是创建一个应用程序,让您将图像加载到画布上,以便对其进行分段mi自动(例如GrabCut)。在我的处理管道中,我定期重新加载绘制的图像以显示遮罩或反映以前步骤的更改。在处理任务中,您生成“n”个中间图像,然后您希望更改显示的图像。我说的对吗?
import QtQuick 2.0
import QtQuick.Controls 2.0

ApplicationWindow {
    id: root
    visible: true
    width: 800
    height: 480

    // =============
    // Event Handler
    // =============
    onHeightChanged: {
        imagePainter.resize()
    } 

    onWidthChanged: {
        imagePainter.resize()
    } 

    // ========
    // Children
    // ========
    Item {
        anchors {
            top: parent.top
            bottom: button.top
            right: parent.right
            left: parent.left
            bottomMargin: 10
        }

        Canvas {
            id: imagePainter
            anchors {
                horizontalCenter: parent.horizontalCenter
                verticalCenter: parent.verticalCenter
            }

            // =================
            // Custom Properties
            // =================
            property var size: {
                'width': -1,
                'height': -1
            }
            property real scale: 1
            property var image: 'image://CustProv/image'

            // =========
            // Functions
            // =========
            function resize() {
                console.log("Resizing canvas contents")
                var wToH =  size.width/size.height
                if (parent.width/parent.height >= wToH) {
                    // image aspect ratio is narrower than parent 
                    // aspect ratio: Use full height
                    height = parent.height
                    width = wToH * parent.height
                    scale = height/size.height
                }
                else {    
                    // image aspect ratio is wider than parent 
                    // aspect ratio: use full width   
                    width = parent.width          
                    height = parent.width / wToH
                    scale = width/size.width
                }
                // repaint the image
                requestPaint();
            }

            function reload() {
                console.log("Reload triggered")
                // First, get the new image size
                var imSize = CustProv.getImageSize()
                size.width = imSize[0]
                size.height = imSize[1]
                resize()

                // Reload image
                unloadImage(image) <--- Seems to fail for small images
                loadImage(image)
            }

            // =============
            // Event Handler
            // =============
            Component.onCompleted: {
                console.log("connecting external signals")
                CustProv.updateImage.connect(reload)
            }

            onPaint: {
                // Invoked by requestPaint()
                if (!isImageLoaded(image)) {
                    return
                }
                var ctx = getContext('2d')
                ctx.clearRect(0, 0, width, height)
                ctx.scale(scale, scale)
                ctx.drawImage(image, 0, 0)
                ctx.scale(1/scale, 1/scale)
            }

            onImageLoaded: {
                requestPaint()
            }
        }
    }


    Button {
        id: button
        anchors {
            right: parent.right
            bottom: parent.bottom
            bottomMargin: 10
            rightMargin: 10
        }

        width: 200
        height: 25

        text: "Change Image"

        onClicked: {
            CustProv.changeImage()
        }
    }
}