Qt:基于QQuickFramebufferObject顯示QImage到QML中

GItHub地址

簡介

本倉庫實現了一個在QML框架中,顯示QImage數據的QML控件,取名為JQImageItem

本控件針對的場合是需要顯示并且頻繁修改QImage的場景,例如視頻顯示。

提供了2個實現版本,一個是基于QQuickFramebufferObject(FBO)的JQImageItem,一個是基于QQuickPaintedItem的JQImageItem2。

在絕大多數場合下,FBO的實現性能要明顯好于其他版本,因此如果你需要使用本倉庫的控件,請使用這個版本。

代碼基于純Qt+OpenGL實現,開發時測試了2個Qt版本,分別是5.15.2和6.5.2,理論上其他Qt版本也能正常使用。

如何使用

在QML中,直接實例化控件,然后需要把控件的指針傳回到C++,然后在C++端進行數據更新。實例化代碼如下:

JQImageItem {id: imageItemanchors.fill: parent
}

如果要調整圖片顯示的大小,位置等屬性,那么直接調整這個Item即可。

在C++端拿到指針后,調用setImage接口,可以把QImage數據設置到控件內,然后控件會顯示這個QImage圖片數據,代碼如下:

imageItem->setImage( QImage( "C:/your/image/xxx.png" ) );

這個setImage接口是線程安全的,因此你可以在任何線程調用這個接口

為什么快?

要理解為什么本倉庫的實現塊,我們需要先理解3個常見的QImage顯示方法

一般來說,在QML中顯示一個QImage,有3個方法實現,他們分別如下:

  • QQuickImageProvider

    這是目前網上最多的實現方法,大致原理是把QImage圖片數據通過圖片顯示的邏輯,傳給QML。

    這個方法理論上是最慢的,因為這個邏輯下,需要把一個圖片,完整的經過Qt的圖片資源處理邏輯,才能顯示到QML中。

    在Qt的設計初衷上,這個類根本不是給這個場景用的,因此大多數人的實現,都需要在QML端給url賦值隨機數,或者一個自增變量,來避免URL相同而引起的圖片不刷新問題。

    并且,這個邏輯下,會嚴重破壞QML的圖片緩存邏輯(如果你不設置cache為false的話)。

    因此在頻繁修改圖片的需求下,這個實現方式,我是完全不推薦使用的。

  • QQuickPaintedItem

    這個類的實現,更加的貼近我們的使用場景,也不存在url這些對實現需求完全無用的中間參數變量等。

    這個類大致的流程是在C++端,通過QPainter繪制一個圖片到QImage中,然后Qt會把這個QImage圖片顯示到QML上

    這個類的速度其實已經很快了,但是他還是存在一個額外的開銷,就是QPainter的步驟。即使在分辨率,格式完全相同的情況下,QPainter繪制一個圖片到QQuickPaintedItem內部的緩沖區,會存在至少一次的拷貝開銷。

    不過這個類本身也有FBO的實現方式,可以說如果你的需求是QPainter繪制圖表,或者其他內容的話,這就是最合適的實現。

  • QQuickFramebufferObject(FBO)

    分析我們的需求,目前已經有了一個QImage,QImage有完整封裝好的圖片數據,我們希望他可以直接傳給OpenGL實現,沒有其他的開銷。那么此時,直接把這個圖片數據,上傳到OpenGL的紋理對象(QOpenGLTexture),然后直接繪制,那么這就是最快的方法。

    基于FBO顯示圖片的話,會比較復雜,大致流程是:

    • 創建自己的shader,只保留圖片渲染需要的部分

    • 創建和圖片渲染相關的VBO,VAO

    • 把圖片根據需求,更新到紋理中

    • 在OpenGL的繪制回調中,調用所有的相關對象,完成圖片繪制

    也就是說基于FBO的實現,雖然邏輯更復雜,代碼更多,但是更精準的控制了相關資源的使用、創建和釋放邏輯。因此獲得了一定的性能優勢。并且在分辨率和格式相同的情況下,紋理不需要重新分配顯存空間,可以復用。

    換句話說,就是特化了QImage顯示的場景,降低了控件的通用性以換取性能。

    另外這里還有一個重要的性能優勢,就是圖片分辨率小于控件分辨率時,不在C++端進行縮放,而是把小圖片直接上傳到紋理,然后由QpenGL在顯示的時候完成縮放邏輯。

    基于FBO也有圖片附件的顯示方法,代碼量更少。但是實測下來性能開銷也很大,因此我自己重寫了shader,沒有使用圖片附件的方法。

注1:圖片附件的代碼如下,有興趣的小伙伴可以自行搜索下文檔:glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0 );

注2:我們暫時不討論AnimatedImage和VideoOutput,因為這2個控件有其他更精準的使用場景

關于測試代碼

測試代碼分為2部分,一個是QML部分,分別實例化了JQImageItem和JQImageItem2,鼠標點擊切換,開發者們可以觀察切換后,CPU和GPU占用情況的變化。

C++的Helper類,會起一個線程,以大約60FPS的速度在設置圖片給JQImageItem,以模擬圖片變化的場合。

測試數據會有一個縮放的效果,這個涉及到的圖片序列已經在初始化的時候生成完畢,并且統一了分辨率。這樣在測試代碼運行過程中的開銷,基本就只有渲染開銷。

心得體會

就如同之前所說,特化代碼,換取了性能優勢。因此這個方法需要更多的代碼量,以及OpenGL相關的知識,大部分開發者不會做到這一步。

對我而言,很久以前就有這個QImage的顯示需求,我都是拿QQuickPaintedItem實現,即使知道了FBO可以更快,但是無奈沒有相關的知識儲備,一直沒有做實現,一直到現在才把這個實現做了出來。

實現的代碼量其實不大,前后加起來就是300行不到。但是我覺得這個功能真的很重要,因此直接開源,方便其他開發者們取用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/719137.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/719137.shtml
英文地址,請注明出處:http://en.pswp.cn/news/719137.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32CubeIDE基礎學習-軟件安裝,環境搭建

STM32CubeIDE基礎學習-軟件介紹及環境搭建步驟 文章目錄 STM32CubeIDE基礎學習-軟件介紹及環境搭建步驟前言第1章 STM32CubeIDE 介紹1.1 軟件描述1.2 軟件支持的功能及特點 第2章 STM32CubeIDE 軟件安裝2.1 STM32CubeIDE 軟件獲取方法2.2 STM32CubeIDE 軟件安裝步驟2.2.1 錯誤安…

C++模板完整版

顧得泉:個人主頁 個人專欄:《Linux操作系統》 《C從入門到精通》 《LeedCode刷題》 鍵盤敲爛,年薪百萬! 一、泛型編程 如何實現一個通用的交換函數呢? void Swap(int& left, int& right) {int temp left…

抖店入駐費用是多少?新手入駐都有哪些要求?2024費用明細!

我是電商珠珠 我做電商做了將近五年,做抖店做了三年多,期間還帶著學員一起做店。 今天,就來給大家詳細的講一下在抖音開店,需要多少費用,最低需要投入多少。 1、營業執照200元左右 就拿個體店舉例,在入…

hook函數——useReducer

目錄 1.useReducer定義2.useReducer用法3.useState和useReducer區別 1.useReducer定義 const [state, dispatch] useReducer(reducer, initialArg, init?) reducer:用于更新 state 的純函數。參數為 state 和 action,返回值是更新后的 state。state …

這波操作看麻了!十億行數據,從71s到1.7s的優化之路。

節期間關注到了一個關于 Java 方面的比賽,很有意思。由于是開源的,我把項目拉下來試圖學(白)習(嫖)別人的做題思路,在這期間一度讓我產生了一個自我懷疑: 他們寫的 Java 和我會的 Ja…

解鎖軟件管理新篇章,Allegro許可證使用規定全解

在數字化經濟的時代,軟件已經成為企業運營的關鍵要素。然而,軟件的使用往往伴隨著一系列的合規性問題,導致企業面臨潛在的風險和成本。Allegro許可證作為業界領先的軟件解決方案提供商,為企業提供全面的許可證使用規定&#xff0c…

每日一題——LeetCode1576.替換所有的問號

方法一 3個字母原則 把?替換為和他左右都不相等的字符,那么找3個字符abc,?總能替換為abc中的一個字符,遍歷字符串找到所有?,再遍歷abc把?替換為abc中的一個字符 var modifyString …

解析 openGauss 的 AutoVacuum 機制及優化策略

前言 在 openGauss 數據庫中,AutoVacuum 機制是一個關鍵的自動化功能,用于管理表的空間和性能。AutoVacuum 通過定期清理過時數據和更新統計信息,幫助數據庫管理員維護數據庫的性能和穩定性。 為什么需要 AutoVacuum? 了解AutoV…

JAVA內存模型與JVM內存結構

注意區分Java內存模型(Java Memory Model,簡稱JMM)與Jvm內存結構,前者與多線程相關,后者與JVM內部存儲相關。本文會對兩者進行簡單介紹。 一、JAVA內存模型(JMM) 1. 概念 說來話長,由于在不同硬件廠商和…

No matching version found for @babel/traverse@^7.24.0.

問題: npm安裝 依賴失敗,找不到所需依賴。 原因: npm鏡像源中沒有該依賴。(大概率是因為依賴最近剛更新,當前鏡像源沒有同步) 解決: 查看自己的npm鏡像:npm config get registry…

機器學習-面經(part2)

3. 驗證方式 3.1什么是過擬合?產生過擬合原因? 定義:指模型在訓練集上的效果很好,在測試集上的預測效果很差 數據有噪聲 訓練數據不足,有限的訓練數據 訓練模型過度導致模型非常復雜3.2 如何避免過擬合問題? 3.3 什么是機器學習的欠擬合?產生原…

D4890可應用在對講機上,采用 SOP8/MSOP8兩種封裝形式

D4890 目前客戶主要使用在對講機上,電壓范圍2.2V ~ 5.5V之間,輸出功率(THDN1%)1.0W/8Ω 5.0V。采用 SOP8/MSOP8兩種封裝形式。 2、推薦的應用線路圖如下: 3、實際測試輸出波形如下(VCC4.5V&…

Web Component 轉圖片

一、HTML 轉圖片 目前,常見的開源的能夠將 HTML 轉換為圖片有html2canvas、dom-to-image,大部分場景下,這些開源庫都能很友好的處理。 HTML 轉圖片的實現原理,通常分為兩種:svg 與 canvas。今天主要討論下 svg 的場景…

Flutter中使用Dio庫封裝網絡請求服務工具類

在Flutter應用程序中,進行網絡請求是非常常見的任務。Dio是一個強大的、易于使用的Dart包,用于處理HTTP請求。本篇博客將介紹如何封裝Dio庫,以及如何在Flutter應用中進行網絡請求并取消請求。 什么是Dio? Dio是一個基于Dart語言…

解決android studio build Output中文亂碼

1.效果如下所示: 代碼運行報錯的時候,Build Output報的錯誤日志中中文部分出現亂碼,導致看不到到底報的什么錯。 2.解決辦法如下: 點擊Android studio開發工具欄的Help-Edit Custom VM Options....,Android studio會…

springboot微服務中集成了mybatis的服務引入了其他集成了mybatis的服務此時調用引入的服務中的某個mapper接口時報沒有注入

在啟動類上加引入的服務中的mapper路徑,在配置文件中將mapperLocations的值改為classpath*:mapper/.xml: MapperScan(basePackages {"com.ruoyi..mapper"}) 和 mapperLocations: classpath*:mapper/*.xml 是 MyBatis 在 Spring Boot 中配置 M…

AutoGPT實現原理

AutoGPT是一種利用GPT-4模型的自動化任務處理系統,其主要特點包括任務分配、多模型協作、互聯網訪問和文件讀寫能力以及上下文聯動記憶性。其核心思想是通過零樣本學習(Zero Shot Learning)讓GPT-4理解人類設定的角色和目標,并通過…

端口號被占用時的解決辦法

1、查看端口占用的進程號 netstat -ano |findstr 8080 2、 找到占用端口的程序 tasklist |findstr 2264 3、kill端口 taskkill /pid 2264 /f

文物預防性保護方案整體結構及軟件介紹

?文物預防性保護監測與調控系統整體是構架在商業級技術平臺上的多層綜合性應用,采用分布式部署的模塊化設計,以智能監測終端及高精傳感器為核心的感知系統。系統通過以下的層次結構協同工作完成全面的監控與調控功能: 1)系統依靠文物監測調控模型作為運行核心&…

基于springboot+vue的校園愛心捐贈互助管理系統(源碼+論文)

目錄 前言 一、功能設計 二、功能實現 三、庫表設計 四、論文 前言 隨著經濟水平和生活水平的提高在校大學生在校需要處理的物品也在不斷增加,同時校園內還存在很多貧困生,可以通過線上平臺實現資源的整合和二次利用,通過線上平臺求助信…