[英]QImage: How to destroy pointer to pixels data properly?
在控制窗口的主類中,我具有以下功能,其中pixmapItem
是在類頭中定義的QGraphicsPixmapItem*
:
void updateDisplay() {
uchar *data = new ...; // array of pixel data
...
QImage image = QImage(data, width, height,
width, QImage::Format_Indexed8);
pixmapItem->setPixmap(QPixmap::fromImage(image));
}
我的問題是:如何在不再需要data
時銷毀data
? “不再需要”表示上面的函數或類中的另一個函數將像素圖設置為另一個圖像。
我已經看到QImage具有清理功能,該功能可能會有所幫助,但是關於如何使用它們以及如何傳遞參數(例如要刪除的圖像數據指針)的文檔尚不清楚。
當QImage
被銷毀時,您可以刪除數據。 如上面的@JeremyFriesner所示,可以通過在內部范圍內定義QImage
實例並在其外部分配/取消分配數據來簡單地完成此操作。
但是,為什么還要煩惱所有這些工作呢? QImage
構造函數可以適應復雜的用例,在這些用例中您已經具有來自其他來源的像素數據,或者需要在“奇怪的”生命周期內保留它。
相反,您的情況更簡單,像素數據的壽命與QImage
完全相同,因此最好讓它自己為像素分配內存; 這樣,您可以確定它的大小和對齊方式正確,並且由QImage
實例擁有/自動銷毀; 構造完QImage
對象后,您可以使用bits
方法使用一個指向像素數據的指針,並對其進行任何操作。
這樣,您的代碼將變成:
void updateDisplay() {
QImage image = QImage(width, height,
width, QImage::Format_Indexed8);
uchar *data = image.bits();
...
pixmapItem->setPixmap(QPixmap::fromImage(image));
}
更簡單,更安全,內存泄漏風險為零。
從Qt文檔
構造具有給定寬度,高度和格式的圖像,該圖像使用現有的內存緩沖區數據。 寬度和高度必須以像素為單位指定,數據必須是32位對齊的,並且圖像中數據的每條掃描線也必須是32位對齊的。
緩沖區必須在QImage的整個生命周期內保持有效。 映像不會刪除銷毀的緩沖區。
您需要實現自己的方式來刪除該緩沖區
因此,您需要自己刪除data
,但是當然,訣竅不是不要過早刪除它-特別是,當QImage對象可能仍在使用它時,您不想刪除它。 在您的情況下,最簡單的方法是僅在銷毀QImage對象之后將其刪除:
void updateDisplay() {
uchar *data = new ...; // array of pixel data
...
{
QImage image = QImage(data, width, height,
width, QImage::Format_Indexed8);
pixmapItem->setPixmap(QPixmap::fromImage(image));
}
delete [] data;
}
(請注意使用花括號創建內部范圍,從而確保在執行delete [] data
行之前 ,將QImage對象從堆棧中彈出並銷毀!)
當然,更簡單,更安全的方法是完全不必首先刪除數組,從而避免了何時刪除的問題。 相反,讓QImage對象分配其自己的數據數組,然后直接寫入該數據數組:
QImage image(width, height, QImage::Format_Indexed8);
char * data = image.bits();
// write into (data) here if you want to, but don't delete [] data, ever!
// instead, the QImage destructor will do any necessary deletes for you
您可以使用自己的析構函數對QImage
進行子類化,以進行清理。
class NativeBufferQImage : public QImage {
uchar *data;
// other stuff
public:
~NativeBufferQImage() {
delete[] this->data;
}
};
還要注意,由於QImage
是從QPaintDevice
派生的,並且QPaintDevice
具有虛擬析構函數 ,因此,如果有人通過指向其基類的指針(即QImage
) delete
NativeBufferQImage
,那么也會調用您的析構函數。
最好的方法是不要這樣做:
void updateDisplay() {
QImage image(width, height, QImage::Format_Indexed8);
auto const data = image.bits();
// you can modify the data here
pixmapItem->setPixmap(QPixmap::fromImage(image));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.