|
|
@@ -0,0 +1,247 @@
|
|
|
+#include "InteractiveFace.h"
|
|
|
+
|
|
|
+#include <QMediaDevices>
|
|
|
+#include <QRandomGenerator>
|
|
|
+#include <QTimerEvent>
|
|
|
+#include <QPainter>
|
|
|
+#include <QFont>
|
|
|
+#include <QPen>
|
|
|
+
|
|
|
+InteractiveFace* InteractiveFace::pInstance = nullptr;
|
|
|
+
|
|
|
+InteractiveFace::InteractiveFace(QObject *parent)
|
|
|
+ : QQuickImageProvider(QQuickImageProvider::Image)
|
|
|
+{
|
|
|
+ if (hasCamera())
|
|
|
+ {
|
|
|
+ // initCamera();
|
|
|
+ }
|
|
|
+ // 图像取1s 10帧
|
|
|
+ m_timerId = startTimer(100);
|
|
|
+}
|
|
|
+
|
|
|
+InteractiveFace::~InteractiveFace()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+QString InteractiveFace::getImageUrl()
|
|
|
+{
|
|
|
+ // image://InteractiveFaceImage/(0-9999)
|
|
|
+ return QString("image://") +
|
|
|
+ QString(INTERACTIVE_FACE_IMAGE_URL) +
|
|
|
+ QString("/") +
|
|
|
+ // 取随机数,确保图片刷新(Qt机制,两次url地址相同,图片不会显示)
|
|
|
+ QString::number(QRandomGenerator::global()->bounded(10000));
|
|
|
+}
|
|
|
+
|
|
|
+InteractiveFace *InteractiveFace::instance()
|
|
|
+{
|
|
|
+ if (!pInstance) {
|
|
|
+ pInstance = new InteractiveFace(nullptr);
|
|
|
+ }
|
|
|
+ return pInstance;
|
|
|
+}
|
|
|
+
|
|
|
+InteractiveFace *InteractiveFace::create(QQmlEngine *, QJSEngine *)
|
|
|
+{
|
|
|
+ return instance();
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::setCameraImageGatherCallBack(QJSValue callback)
|
|
|
+{
|
|
|
+ m_imageGatherCallback = callback;
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::setCameraImageAppearCallBack(QJSValue callback)
|
|
|
+{
|
|
|
+ m_imageAppearCallback = callback;
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::setCameraImageRemainCallBack(QJSValue callback)
|
|
|
+{
|
|
|
+ m_imageRemainCallback = callback;
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::setCameraImageCallBack(QJSValue gatherCallback, QJSValue appearCallback, QJSValue remainCallback)
|
|
|
+{
|
|
|
+ m_imageGatherCallback = gatherCallback;
|
|
|
+ m_imageAppearCallback = appearCallback;
|
|
|
+ m_imageRemainCallback = remainCallback;
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::setCallBackFaceStatus(QJSValue isAppearCallback)
|
|
|
+{
|
|
|
+ m_isAppearCallback = isAppearCallback;
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::cameraImagePlay()
|
|
|
+{
|
|
|
+ if (!hasCamera())
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (!m_camera.isActive())
|
|
|
+ {
|
|
|
+ cameraPlay();
|
|
|
+ m_laseEpoch = 0;
|
|
|
+ m_laseCount = 0;
|
|
|
+
|
|
|
+ m_FrameId = 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::cameraImageStop()
|
|
|
+{
|
|
|
+ if (!hasCamera())
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ cameraStop();
|
|
|
+}
|
|
|
+
|
|
|
+QImage InteractiveFace::getImage()
|
|
|
+{
|
|
|
+ QMutexLocker locker(&m_mutex);
|
|
|
+ return m_image.copy();
|
|
|
+}
|
|
|
+
|
|
|
+QImage InteractiveFace::requestImage(const QString &, QSize *, const QSize &)
|
|
|
+{
|
|
|
+ return m_image;
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::timerEvent(QTimerEvent *event)
|
|
|
+{
|
|
|
+ if (event->timerId() == m_timerId)
|
|
|
+ {
|
|
|
+ if (!hasCamera())
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (m_camera.isActive())
|
|
|
+ {
|
|
|
+ QMutexLocker locker(&m_mutex);
|
|
|
+ QVideoFrame currentFormat = m_videoSink.videoFrame();
|
|
|
+
|
|
|
+ QImage image; // 图像
|
|
|
+ QPainter painter; // 画笔
|
|
|
+
|
|
|
+ // 过滤无效帧, 前10帧不做处理
|
|
|
+ if(++m_FrameId <= 30)
|
|
|
+ {
|
|
|
+ m_image = image.copy();
|
|
|
+ if (m_imageGatherCallback.isCallable())
|
|
|
+ {
|
|
|
+ QJSValueList args;
|
|
|
+ args << getImageUrl();
|
|
|
+ m_imageGatherCallback.call(args);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (currentFormat.isValid())
|
|
|
+ {
|
|
|
+ if (currentFormat.map(QVideoFrame::ReadOnly))
|
|
|
+ {
|
|
|
+ image = currentFormat.toImage();
|
|
|
+ // image = image.scaled(QSize(800, 600), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
|
|
+ }
|
|
|
+ currentFormat.unmap();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!image.isNull())
|
|
|
+ {
|
|
|
+ // image底部框
|
|
|
+ painter.begin(&image);
|
|
|
+ painter.setRenderHint(QPainter::Antialiasing);
|
|
|
+ painter.setFont(QFont("Arial", 24));
|
|
|
+ painter.setBrush(QColor(255, 255, 255, 127));
|
|
|
+ painter.setPen(Qt::NoPen);
|
|
|
+ painter.drawRect(QRect(0, image.height() - 50, image.width(), 50));
|
|
|
+
|
|
|
+ // TODO: 绘制人脸区域
|
|
|
+ // QImage convertedImage = image.convertToFormat(QImage::Format_RGB888);
|
|
|
+
|
|
|
+ painter.end();
|
|
|
+
|
|
|
+ m_image = image.copy();
|
|
|
+
|
|
|
+ if (m_imageGatherCallback.isCallable())
|
|
|
+ {
|
|
|
+ QJSValueList args;
|
|
|
+ args << getImageUrl();
|
|
|
+ m_imageGatherCallback.call(args);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::initCamera()
|
|
|
+{
|
|
|
+ m_camera.setCameraDevice(QMediaDevices::defaultVideoInput());
|
|
|
+
|
|
|
+ QCameraDevice device = QMediaDevices::defaultVideoInput();
|
|
|
+ QList<QCameraFormat> formats = device.videoFormats();
|
|
|
+ // 选择最适合的格式
|
|
|
+ for (auto &format : formats)
|
|
|
+ {
|
|
|
+ // qDebug() << "fps---" << format.maxFrameRate() << format.resolution().width() << format.resolution().height();
|
|
|
+ if (format.maxFrameRate() >= 10.0 && format.resolution().width() % 4 == 0)
|
|
|
+ {
|
|
|
+ m_camera.setCameraFormat(format);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ m_session.setCamera(&m_camera);
|
|
|
+ m_session.setVideoSink(&m_videoSink);
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::destroyCamera()
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+bool InteractiveFace::hasCamera()
|
|
|
+{
|
|
|
+ return !QMediaDevices::videoInputs().isEmpty();
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::cameraPlay()
|
|
|
+{
|
|
|
+ // 如果相机不是播放状态
|
|
|
+ if (!m_camera.isActive())
|
|
|
+ {
|
|
|
+ QCameraDevice cameraDevice = QMediaDevices::defaultVideoInput();
|
|
|
+ if (cameraDevice.isNull())
|
|
|
+ {
|
|
|
+ qWarning() << "系统中没有检测到任何摄像机设备";
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ m_camera.setCameraDevice(cameraDevice);
|
|
|
+
|
|
|
+ m_session.setCamera(&m_camera);
|
|
|
+ m_session.setVideoSink(&m_videoSink);
|
|
|
+
|
|
|
+ m_camera.start();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void InteractiveFace::cameraStop()
|
|
|
+{
|
|
|
+ if (m_camera.isActive())
|
|
|
+ {
|
|
|
+ m_camera.stop();
|
|
|
+ m_camera.setActive(false);
|
|
|
+ m_camera.setCameraDevice(QCameraDevice());
|
|
|
+
|
|
|
+ m_session.setCamera(nullptr);
|
|
|
+ m_session.setVideoSink(nullptr);
|
|
|
+ }
|
|
|
+}
|