QT例程只能在 电脑正常 预览,取景,在ANDROID 能拍照,但不能预览、取景;
几年前写过修改 QtAndroid 的 JAVA 类, 其关联文件较多,在些的修改只要新建一个类就可以了,
新建类 MyVideoSurface
#ifndef MYVIDEOSURFACE_H
#define MYVIDEOSURFACE_H
#include <QAbstractVideoSurface>
#include <QDebug>
#include <QVideoSurfaceFormat>
#include <QVideoFrame>
class MyVideoSurface : public QAbstractVideoSurface
{
Q_OBJECT
public:
MyVideoSurface(QObject *parent = nullptr);
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType type = QAbstractVideoBuffer::NoHandle) const Q_DECL_OVERRIDE;
bool isFormatSupported(const QVideoSurfaceFormat &) const Q_DECL_OVERRIDE; //将视频流中像素格式转换成格式对等的图片格式,若无对等的格式,返回QImage::Format_Invalid
bool start(const QVideoSurfaceFormat &) Q_DECL_OVERRIDE; //只要摄像头开,就会调用
bool present(const QVideoFrame &) Q_DECL_OVERRIDE; //每一帧画面将回到这里处理
void stop() Q_DECL_OVERRIDE;
signals:
void frameAvailable(QVideoFrame cloneFrame);
};
#endif // MYVIDEOSURFACE_H
#include "myvideosurface.h"
MyVideoSurface::MyVideoSurface(QObject *parent) :QAbstractVideoSurface(parent)
{
}
//支持的像素格式
QList<QVideoFrame::PixelFormat> MyVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
if(handleType == QAbstractVideoBuffer::NoHandle){
return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_RGB32
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_NV21
<< QVideoFrame::Format_RGB555;
}
else {
return QList<QVideoFrame::PixelFormat>();
}
}
//将视频流中像素格式转换成格式对等的图片格式,若无对等的格式,返回QImage::Format_Invalid
bool MyVideoSurface::isFormatSupported(const QVideoSurfaceFormat &videoformat) const
{
//imageFormatFromPixelFormat()-----返回与视频帧像素格式等效的图像格式
//pixelFormat()-----返回视频流中帧的像素格式
return QVideoFrame::imageFormatFromPixelFormat(videoformat.pixelFormat()) != QImage::Format_Invalid;
}
//这些虚函数,会自动被调用,start检测图像是否可以对等转换,每一帧有没有
bool MyVideoSurface::start(const QVideoSurfaceFormat &videoformat)
{
QAbstractVideoSurface::start(videoformat);
return false;
}
bool MyVideoSurface::present(const QVideoFrame &frame)
{
// qDebug() << frame.size();
if (frame.isValid()){
QVideoFrame cloneFrame(frame); //每一帧视频都会进入present中,内部机制
emit frameAvailable(cloneFrame); //直接把视频帧发送出去
return true;
}
stop();
return false;
}
void MyVideoSurface::stop()
{
QAbstractVideoSurface::stop();
}
// 修改文件 #include "camera.h"
#include "myvideosurface.h" // 新加的
....
class Camera : public QMainWindow
{
Q_OBJECT
public:
Camera();
.......
private:
MyVideoSurface *mySurface; // 新加的
};
#endif
// 修改文件 "camera.cpp"
// 修改代码
void Camera::setCamera(const QCameraInfo &cameraInfo)
{
......
connect(ui->exposureCompensation, &QAbstractSlider::valueChanged, this, &Camera::setExposureCompensation);
m_camera->setViewfinder(mySurface); // 修改处理
connect(mySurface, SIGNAL(frameAvailable(QVideoFrame)), ui->viewfinder, SLOT(rcvFrame(QVideoFrame)), Qt::QueuedConnection);// 添加处理
updateCameraState(m_camera->state());
updateLockStatus(m_camera->lockStatus(), QCamera::UserRequest);
.......
ui->captureWidget->setTabEnabled(1, (m_camera->isCaptureModeSupported(QCamera::CaptureVideo)));
updateCaptureMode();
m_camera->load();// 添加处理
m_camera->start();
// QList<QCameraViewfinderSettings> cvs= m_camera->supportedViewfinderSettings();
// for(int i=0;i<cvs.size();i++)
// {
// qDebug()<<"CVS:"<<cvs[i].pixelFormat()<<cvs[i].resolution()<<cvs[i].pixelAspectRatio()<<cvs[i].minimumFrameRate()<<cvs[i].maximumFrameRate();
// }
//设置摄像头参数// 添加处理
QCameraViewfinderSettings camerasettings = m_camera->viewfinderSettings();
// camerasettings.setResolution(1920,1080); // 手机处理能力不强时,不要设置过大
camerasettings.setResolution(1280,720);
camerasettings.setPixelFormat(QVideoFrame::Format_NV21);
camerasettings.setMaximumFrameRate(30);
camerasettings.setMinimumFrameRate(25);// 不要小于20,会不畅
m_camera->setViewfinderSettings(camerasettings);
}