[英]Saving a QImage from a memory buffer
這基本上是我在做什么:
我有一個視頻流(YUV格式)。 每個幀都提取到緩沖區( frameBytes
)中。 以后,此緩沖區用於執行YUV-> RGB轉換,然后在IplImage
中進行IplImage
。 然后將IplImage
傳輸到cv::Mat
並顯示在OpenGL上下文中。 一切正常。
我想做的是繞過IplImage
和cv::Mat
部分,直接在OpenGL中使用frameBytes
緩沖區,並在着色器中進行轉換。
這種解釋僅是針對上下文,因為我遇到的問題比較簡單。
為了查看我是否可以更早使用該緩沖區,我嘗試使用memcpy復制它,然后將其保存在QImage
,然后保存在文件中。
這是我這部分的代碼:
unsigned char *mycopy = new unsigned char[1920*1080*3];
memcpy(mycopy, frameBytes, sizeof(1920*1080*3));
QImage *img = new QImage(mycopy, 1920, 1080, QImage::Format_RGB888);
img->save("image.jpg",0,-1);
frameBytes包含來自視頻流的YUV數據。 我知道它是YUV,並且我正在嘗試創建具有RGB888格式的QImage,但是由於QImage不支持該格式,因此我沒有在那里進行轉換,所以我認為它仍然可以保存圖像但顏色錯誤,所以我暫時不關心(也許這個假設是錯誤的?)。
問題是,保存的圖像是黑色的。
只是為了獲得更多信息,這是一個示例,其中我使用frameBytes
進行frameBytes
> RGB轉換。
void DeckLinkCaptureDelegate::convertFrameToOpenCV(void* frameBytes, IplImage * m_RGB){
if(!m_RGB) m_RGB = cvCreateImage(cvSize(1920, 1080), IPL_DEPTH_8U, 3);
unsigned char* pData = (unsigned char *) frameBytes;
for(int i = 0, j=0; i < 1920 * 1080 * 3; i+=6, j+=4)
{
unsigned char u = pData[j];
unsigned char y = pData[j+1];
unsigned char v = pData[j+2];
//fprintf(stderr, "%d\n", v);
m_RGB->imageData[i+2] = 1.0*y + 8 + 1.402*(v-128); // r
m_RGB->imageData[i+1] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128); // g
m_RGB->imageData[i] = 1.0*y + 1.772*(u-128) + 0; // b
y = pData[j+3];
m_RGB->imageData[i+5] = 1.0*y + 8 + 1.402*(v-128); // r
m_RGB->imageData[i+4] = 1.0*y - 0.34413*(u-128) - 0.71414*(v-128); // g
m_RGB->imageData[i+3] = 1.0*y + 1.772*(u-128) + 0;
}
}
您沒有將所有數據復制到新緩沖區中:
unsigned char *mycopy = new unsigned char[1920*1080*3];
memcpy(mycopy, frameBytes, sizeof(1920*1080*3));
那里的sizeof
意味着您只復制一個int
大小的塊,而不是6MB。 看起來是由於使用靜態數組導致的意外保留? 替換為
const size_t bufsize = 1920*1080*3;
auto *mycopy = new unsigned char[bufsize];
memcpy(mycopy, frameBytes, bufsize);
另外,您可以復制映像,而不是自己進行內存分配(並在QImage
銷毀后負責delete[]
對其進行分配):
const unsigned char *bytes = frameBytes;
QImage img = QImage(bytes, 1920, 1080, QImage::Format_RGB888).copy();
這種工作方式是,我們使用frameBytes
作為其源創建一個臨時QImage
(我們將其作為指向const
指針傳遞,以使其堅持為只讀)。 然后,我們將整個過程都copy()
到新的QImage
,丟棄臨時圖像。 copy()
功能與您上面的代碼類似,但是現在不必進行計算了,從而避免了隨之而來的潛在錯誤。
另請注意,我更喜歡按值傳遞QImage
。 盡管這看起來效率低下,但大多數(可復制)Qt類型都被設計為引用計數寫時復制結構,可以安全地以這種方式使用,從而消除了另一類錯誤(內存管理)。 Qt的集合類型也是如此,並且非常有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.