Qt QImage載入記憶體資料後繪製

2021-10-24 01:15:36 字數 2473 閱讀 3901

如果我在記憶體中生成了乙個包含rgba各分量的顏色二維陣列colorarray,要怎樣通過qimage把這些資料顯示出來呢?

①qimage需要載入這些資料

//1、 通過qimage的建構函式 

qimage(const uchar *data, int width, int height, format format, qimagecleanupfunction cleanupfunction = q_nullptr,

void *cleanupinfo = q_nullptr);

//其中data是指向顏色資料(32bit)的指標,width表示一行有多少個畫素,height表示一列有多少個畫素,format表示影象格式(qimage

//提供了多種格式)。qimage在析構時並不會刪除data。如果提供了cleanupfunction和cleanupinfo,那麼當qimage的影象資料不再被使用時,

//會呼叫cleanupfunction清除cleanupinfo所指向的記憶體。

//通過靜態函式 qimage::fromdata 還沒嘗試過

②記憶體中colorarray的格式需要和qimage的資料格式一致。

存在qimage中的每乙個畫素都是以整型integer來表示的。這個integer的size以及每個byte的意義,與qimage的格式有關 。qimage支援的顏色資料格式有很多種,比如qimage::format_rgb16、qimage::format_rgba8888、qimage::format_argb32等等。

兩種格式的不同

格式型別

不同點 

qimage::format_argb32

32bit的argb,按32bit整型去訪問,始終是0xaarrggbb。如果按位元組來讀取(也就是儲存方式相關),在不同的系統上,讀取的順序不同。如果在大端big_endian架構上,按位元組會被讀取為0xaa、0xrr、0xgg、0xbb;在小端little_endian架構上,按位元組會被讀取為0xbb、0xgg、0xrr、0xaa。  可以記作,byte儲存方式順序不定,4-byte讀取的數值固定。

qimage::format_rgba8888

每乙個32bit中,rgba各分量的順序是有序的。如果按位元組來讀取,那麼會依次讀取位元組0xrr、0xgg、0xbb、0xaa。那麼,在大端big_endian上,這個32bits會被表示為0xrrggbbaa,在小端little_endian上,會被表示為0xaabbggrr。    可以記作,byte儲存方式順序固定,4-byte讀取的數值不定。

從上面的**中可以看出,對於一塊colorarray,如果用不同的qimage::fromat,可能會產生不同的影象。

我們的問題是,如果用這塊buffer,直接套用qimage(colorarray,width,height, format)的建構函式,如何生成乙個qimage::format_rgba8888的qimage?

在大端big_endian結構上,qimage::format_rgba8888對應的byte順序是 0xrr、0xgg、0xbb、0xaa,所以我們在buffer中賦值時,應依給每個byte位元組幅值rr、gg、bb、aa。或者使用如下結構體直接給32bits賦值。

typedef struct

color;

/*注意,使用這種結構計算出rgba的各分量後,形成了一塊顯示記憶體區域colorarray.

對於這塊colorarray, qimage是直接以int*指標來訪問的。通常情況下,這沒有問題。

但是,如果還要對基於這塊colorarray的qimage進行一次縮放(qimage::scales(...)),則容易出現問題。

因為,進行一次縮放,涉及對colorarray的遍歷,會用int*的指標進行訪問,但是,由於colorarray是用

color物件構造的,colorarray並不一定存放在與int對齊的位址上,因此,用int*指標訪問會導致「段錯誤」。

那麼,如何避免這種情況呢?有這麼2個思路:

1.將colorarray拷貝到乙個int型別的陣列上colorarrayint,qimage用colorarrayint構造

2.typedef unioncolorunion;通過構造聯合體,確保color是與int型別對齊的。

無論對於大端還是小端系統,無論是棧上還是堆上,color::red的位址都小於color::alpha;相應的,int32 temp[4]中,

temp[0]的位址小於temp[4]的位址。

但是,在大端系統中,int32型別變數的第乙個byte對應高8位資料,int32型別變數的地4個位元組,對應低8未資料;

在小端系統中,int32型別變數的第乙個byte,對應低8位資料,int32型別變數的地4個位元組,對應高8未資料。

大端和小端的概念,僅在於變數型別內部如何安排byte,但是變數和變數之間,還是按照通常的順序排布。

*/

附件:

qimage::format列表(待更新....)

DLL記憶體載入

動態載入dll 功能 把乙個處於記憶體裡的dll直接載入並且使用。用途 免殺 靜態檔案查殺 外掛程式 防止遊戲自己hook了loadlibrary等函式 以及其他。原理 假設目前處於記憶體裡的dll是a,然後開闢乙個新的記憶體空間b,根據a的檔案頭等相關資訊,把b看做是載入記憶體。然後把資料拷貝到b...

記憶體載入Dll

分享乙份自己之前總結以前的 寫的dll記憶體載入庫c 版本 專案要自行編譯生成lib檔案 支援 1.win32標準dll 2.mfc dll 3.易語言dll 4.其他環境下生成的dll 但不能加殼加密 file include ldr.h ldr header ifndef ldr h defin...

預設載入資料分頁,點選分頁後再次非同步資料

現在主流的分頁外掛程式很多是一次性把資料載入完成,再本地分頁,切換時候是tab效果,資料量大or網路不通暢的時候,就會很卡影響載入效果。實現每頁載入固定條數及點選分頁再次請求資料,假設共100條資料,一頁10條的話共10頁。需要後端配合每頁顯示全部的條數及每頁條數。根據pagenum 1查詢,返回j...