Python 重新加载QML画布图像
我正在使用QML画布绘制图像。使用Python、OpenCV和NumPy在后端加载映像,并通过从QQuickImageProvider继承的自定义映像提供程序提供给QML。要在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
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()
}
}
}