我遇到Qt问题。
以下是困扰我的代码的一部分:
void FullScreenImage::QImageIplImageCvt(IplImage *input)
{
help=cvCreateImage(cvGetSize(input), input->depth, input->nChannels);
cvCvtColor(input, help, CV_BGR2RGB);
QImage tmp((uchar *)help->imageData, help->width, help->height, help->widthStep, QImage::Format_RGB888);
this->setPixmap(QPixmap::fromImage(tmp).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
cvReleaseImage(&help);
}
void FullScreenImage::hideOnScreen() {
this->hide();
this->clear();
}
void FullScreenImage::showOnScreen(IplImage *slika, int delay) {
QImageIplImageCvt(slika);
this->showFullScreen();
if(delay>0)
QTimer::singleShot(delay*1000, this, SLOT(hideOnScreen()));
}
因此,方法showOnScreen
使用私有方法QImageIplImageCvt
从QImage
创建IplImage
(由OpenCV使用),然后用于创建QPixmap
1}}以全屏显示图像。 FullScreenImage
类继承QLabel
。
经过一段时间的延迟后,应该隐藏全屏图片,因此我会在延迟一段时间后使用QTimer
来触发事件。事件处理程序是hideOnScreen
方法,它隐藏标签并清除内存。
问题如下:
每当我调用QPixmap::fromImage
时,它会为pixmap数据分配内存,并将数据从QImage
内存缓冲区复制到QPixmap
内存缓冲区。隐藏标签后,QPixmap
数据仍然会被分配,更糟糕的是,在新的QPixmap::fromImage
调用之后,新的内存块被分配给新图片,并且旧数据不会从记忆。这会导致内存泄漏(使用我的测试图片每次方法调用10 MB)。我怎样才能解决这个漏洞?
我甚至尝试创建一个私有的QPixmap
变量,将QPixmap::fromImage
创建的pixmap存储到它,然后尝试用hideOnScreen
方法调用它的析构函数,但它没有没帮忙。
是否存在从QPixmap
创建QImage
的非静态方法?或者甚至更好,有没有办法直接从QPixmap
创建IplImage*
?
提前感谢您的回答。
答案 0 :(得分:1)
无法直接从QPixmap
创建IplImage*
(也不能从cv::Mat
创建)。但是,你的解决方案是避免将所有内容写入一行,并使用一个你自己解放的指针。
e.g:
if (this->mypixmap)
delete this->mypixmap;
this->mypixmap = new QPixmap(QPixmap::fromImage(tmp).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
this->setPixmap(this->mypixmap);
不要忘记在构造函数中设置mypixmap(NULL)
。
答案 1 :(得分:0)
您应该可以使用QPixmap::loadFromData
直接创建QPixmap
。所以类似下面的内容可能会起作用:
QPixmap p;
p.loadFromData((uchar *)help->imageData, help->width * help->height);
在不了解OpenCV或IplImage
的情况下,我不能保证上面的代码段是正确的,但希望它能让你走上正确的道路。
答案 2 :(得分:0)
我有类似的问题,但是我的代码不同,所以不值得我放在这里。拿你的代码并与我的方法合并会给你:
void FullScreenImage::QImageIplImageCvt(IplImage *input)
{
help=cvCreateImage(cvGetSize(input), input->depth, input->nChannels);
cvCvtColor(input, help, CV_BGR2RGB);
QImage* tmp = new QImage((uchar *)help->imageData, help->width, help->height, help->widthStep, QImage::Format_RGB888);
this->setPixmap(QPixmap::fromImage(*tmp).scaled(this->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
delete tmp;
cvReleaseImage(&help);
}
答案 3 :(得分:0)
使用重载方法为我解决了这个问题:
QPixmap::fromImage(const QImage && image,..)
您可以通过以下方式调用它:
QPixmap::fromImage(std::move(tmp))