以前不知道onvif也可以做抓拍功能,直到近期重新用Onvif Device Test Tool工具测试的时候,发现还有抓图的接口,于是抓跑分析出要收发的数据,然后加入到自己封装的onvif操作类中,这个抓图有个应用场景就是报警以后,直接通过onvif抓图,而不需要打开实时视频流,基本上不占用什么资源。
抓拍图片流程
onvif主要的功能
onvif的处理流程
QString OnvifDevice::getSnapshotUri(const QString &profileToken)
{
QString file = OnvifHelper::getFile(":/send/getSnapshotUri.xml");
file = file.arg(request->getUserToken()).arg(profileToken);
QByteArray dataSend = file.toUtf8();
QNetworkReply *reply = request->post(mediaUrl, dataSend);
emit sendData(dataSend, mediaUrl);
QByteArray dataReceive;
bool ok = checkData(reply, dataReceive, "请求截图");
if (ok) {
OnvifQuery query;
query.setData(dataReceive);
snapUrl = query.getSnapUrl();
if (!snapUrl.isEmpty()) {
//重新加上用户认证,取图片也需要认证的
emit receiveInfo(snapUrl);
QString userInfo = QString("http://%1:%2@").arg(userName).arg(userPwd);
snapUrl = snapUrl.replace("http://", userInfo);
}
}
return snapUrl;
}
QImage OnvifDevice::snapImage(const QString &profileToken)
{
//这里还可以考虑过滤,比如已经存在了 snapUrl 则不需要去获取地址
getSnapshotUri(profileToken);
QImage image;
if (!snapUrl.isEmpty()) {
//请求图片数据回复 1080P 大概需要 600ms
//默认采用的是 QEventLoop 同步阻塞获取,并不会卡主界面
QNetworkReply *reply = request->get(snapUrl);
QByteArray dataReceive;
bool ok = checkData(reply, dataReceive, "收到截图", false);
if (ok) {
//下面这行代码非常耗时 1080P 图片大概需要 80ms 如果需要频繁的截图建议放入线程处理
image.loadFromData(dataReceive);
}
}
return image;
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。