基於此thread,有沒有辦法在QML中處理來自相機的圖像而不保存它?在不保存的情況下捕獲圖像
從doc的示例開始,capture()函數將圖像保存到Pictures位置。 我想實現的目標是每秒鐘使用onImageCaptured處理相機圖像,但我不想將其保存到驅動器。
我試過使用onImageSaved信號來實現清理操作,但它也影響onImageCaptured。
基於此thread,有沒有辦法在QML中處理來自相機的圖像而不保存它?在不保存的情況下捕獲圖像
從doc的示例開始,capture()函數將圖像保存到Pictures位置。 我想實現的目標是每秒鐘使用onImageCaptured處理相機圖像,但我不想將其保存到驅動器。
我試過使用onImageSaved信號來實現清理操作,但它也影響onImageCaptured。
如this answer中所述,您可以通過mediaObject
橋接C++和QML。這可以通過objectName
(如在鏈接的答案中)或通過使用專用的Q_PROPERTY
(稍後更多)完成。在這兩種情況下,你應該結束了,像這樣的代碼:
QObject * source // QML camera pointer obtained as described above
QObject * cameraRef = qvariant_cast<QMediaObject*>(source->property("mediaObject"));
一旦你得到了鉤到相機,用它作爲源的QVideoProbe
對象,即
QVideoProbe *probe = new QVideoProbe;
probe->setSource(cameraRef);
連接videoFrameProbed
信號到適當的插槽,即
connect(probe, SIGNAL(videoFrameProbed(QVideoFrame)), this, SLOT(processFrame(QVideoFrame)));
,就是這樣:你現在可以處理processFrame
函數內部框架。這種功能的實現是這樣的:
void YourClass::processFrame(QVideoFrame frame)
{
QVideoFrame cFrame(frame);
cFrame.map(QAbstractVideoBuffer::ReadOnly);
int w {cFrame.width()};
int h {cFrame.height()};
QImage::Format f;
if((f = QVideoFrame::imageFormatFromPixelFormat(cFrame.pixelFormat())) == QImage::Format_Invalid)
{
QImage image(cFrame.size(), QImage::Format_ARGB32);
// NV21toARGB32 convertion!!
//
// DECODING HAPPENS HERE on "image"
}
else
{
QImage image(cFrame.bits(), w, h, f);
//
// DECODING HAPPENS HERE on "image"
}
cFrame.unmap();
}
兩個重要的實施細節在這裏:
QImage
目前支持的,哪些應該由手工轉換YUV format。我在這裏做出了強有力的假設,即所有無效的格式都是YUV。通過當前操作系統的ifdef
的條件可以更好地管理。QImage
可以大大提高表演。對於這個問題我會避免在所有objectName
方法用於獲取的mediaObject
,而是我會register a new type,這樣可以使用Q_PROPERTY
方法。我沿着這行想什麼:
class FrameAnalyzer
{
Q_OBJECT
Q_PROPERTY(QObject* source READ source WRITE setSource)
QObject *m_source; // added for the sake of READ function
QVideoProbe probe;
// ...
public slots:
void processFrame(QVideoFrame frame);
}
其中setSource
很簡單:
bool FrameAnalyzer::setSource(QObject *source)
{
m_source = source;
return probe.setSource(qvariant_cast<QMediaObject*>(source->property("mediaObject")));
}
註冊後像往常一樣,即
qmlRegisterType<FrameAnalyzer>("FrameAnalyzer", 1, 0, "FrameAnalyzer");
您可以直接設置在QML的source
屬性,如下所示:
// other imports
import FrameAnalyzer 1.0
Item {
Camera {
id: camera
// camera stuff here
Component.onCompleted: analyzer.source = camera
}
FrameAnalyzer {
id: analyzer
}
}
這種方法的一大優點是可讀性和Camera
代碼和處理代碼之間的更好的耦合。這是以犧牲(稍微)更高的實施努力爲代價的。
這真的取決於你想要的。如果您只想處理幀(例如搜索標記/ Qr代碼),則可以將[mediaObject](http://doc.qt.io/qt-5/qml-qtmultimedia-camera.html#mediaObject-prop )就是這樣。如果你想做實時過濾和覆蓋,那麼需要做更多的工作。有關第二種場景的更多詳細信息,請參閱[本答案](http://stackoverflow.com/a/33238150/2538363)開頭處的鏈接。 – BaCaRoZzo
我想實現的是掃描QR碼。由於我不能使用grabWindow(),因爲[this](https://bugreports.qt.io/browse/QTBUG-53083),我想每秒捕獲一次攝像頭輸出並處理圖像。 – ABCplus
因此,根據您使用mediaObject的建議,一旦我獲得對QCamera對象的引用,那麼我需要做什麼? – ABCplus