#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ss_log("程序正常运行.\n");
}
Widget::~Widget()
{
delete ui;
}
bool checkPermission_usb() {
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.USB_PERMISSION");
if(r == QtAndroid::PermissionResult::Denied) {
QtAndroid::requestPermissionsSync( QStringList() << "android.permission.USB_PERMISSION" );
r = QtAndroid::checkPermission("android.permission.USB_PERMISSION");
if(r == QtAndroid::PermissionResult::Denied) {
return false;
}
}
return true;
}
bool checkPermission_usb2() {
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.hardware.usb.host");
if(r == QtAndroid::PermissionResult::Denied) {
QtAndroid::requestPermissionsSync( QStringList() << "android.hardware.usb.host" );
r = QtAndroid::checkPermission("android.hardware.usb.host");
if(r == QtAndroid::PermissionResult::Denied) {
return false;
}
}
return true;
}
bool requestPermission() {
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.CAMERA");
if(r == QtAndroid::PermissionResult::Denied) {
QtAndroid::requestPermissionsSync( QStringList() << "android.permission.CAMERA" );
r = QtAndroid::checkPermission("android.permission.CAMERA");
if(r == QtAndroid::PermissionResult::Denied) {
return false;
}
}
return true;
}
int Widget::Camear_Init()
{
checkPermission_usb();
checkPermission_usb2();
requestPermission();
bool r_run;
/*创建摄像头对象,根据选择的摄像头打开*/
camera = new QCamera(m_camera);
if(camera==nullptr)return -1;
connect(camera, QOverload<QCamera::Error>::of(&QCamera::error),
[=](QCamera::Error value)
{
if(value!=QCamera::NoError)
{
emit ss_log("摄像头初始化错误!\n");
}
});
m_pProbe = new QVideoProbe;
if(m_pProbe==nullptr)return -1;
r_run=m_pProbe->setSource(camera); // Returns true, hopefully.
if(r_run==false)return -1;
connect(m_pProbe, SIGNAL(videoFrameProbed(QVideoFrame)),this, SLOT(slotOnProbeFrame(QVideoFrame)),Qt::DirectConnection);
/*配置摄像头捕 QCamera *camera;
QVideoProbe *m_pProbe;获模式为帧捕获模式*/
camera->setCaptureMode(QCamera::CaptureVideo);
/*设置摄像头的采集帧率和分辨率*/
QCameraViewfinderSettings settings;
settings.setPixelFormat(QVideoFrame::Format_NV12); //设置像素格式 Android上只支持NV21格式
settings.setResolution(QSize(m_recv_w,m_recv_h)); //设置摄像头的分辨率
camera->setViewfinderSettings(settings);
/*启动摄像头*/
camera->start();
return 0;
}
/*
函数功能: 将YUV数据转为RGB格式
函数参数:
unsigned char *yuv_buffer: YUV源数据
unsigned char *rgb_buffer: 转换之后的RGB数据
int iWidth,int iHeight : 图像的宽度和高度
*/
void yuyv_to_rgb(unsigned char *yuv_buffer,unsigned char *rgb_buffer,int iWidth,int iHeight)
{
int x;
int z=0;
unsigned char *ptr = rgb_buffer;
unsigned char *yuyv= yuv_buffer;
for (x = 0; x < iWidth*iHeight; x++)
{
int r, g, b;
int y, u, v;
if (!z)
y = yuyv[0] << 8;
else
y = yuyv[2] << 8;
u = yuyv[1] - 128;
v = yuyv[3] - 128;
r = (y + (359 * v)) >> 8;
g = (y - (88 * u) - (183 * v)) >> 8;
b = (y + (454 * u)) >> 8;
*(ptr++) = (r > 255) ? 255 : ((r < 0) ? 0 : r);
*(ptr++) = (g > 255) ? 255 : ((g < 0) ? 0 : g);
*(ptr++) = (b > 255) ? 255 : ((b < 0) ? 0 : b);
if(z++)
{
z = 0;
yuyv += 4;
}
}
}
void NV21_TO_RGB24(unsigned char *yuyv, unsigned char *rgb, int width, int height)
{
const int nv_start = width * height ;
int index = 0, rgb_index = 0;
uint8_t y, u, v;
int r, g, b, nv_index = 0,i, j;
for(i = 0; i < height; i++){
for(j = 0; j < width; j ++){
//nv_index = (rgb_index / 2 - width / 2 * ((i + 1) / 2)) * 2;
nv_index = i / 2 * width + j - j % 2;
y = yuyv[rgb_index];
u = yuyv[nv_start + nv_index ];
v = yuyv[nv_start + nv_index + 1];
r = y + (140 * (v-128))/100; //r
g = y - (34 * (u-128))/100 - (71 * (v-128))/100; //g
b = y + (177 * (u-128))/100; //b
if(r > 255) r = 255;
if(g > 255) g = 255;
if(b > 255) b = 255;
if(r < 0) r = 0;
if(g < 0) g = 0;
if(b < 0) b = 0;
index = rgb_index % width + (height - i - 1) * width;
//rgb[index * 3+0] = b;
//rgb[index * 3+1] = g;
//rgb[index * 3+2] = r;
//颠倒图像
//rgb[height * width * 3 - i * width * 3 - 3 * j - 1] = b;
//rgb[height * width * 3 - i * width * 3 - 3 * j - 2] = g;
//rgb[height * width * 3 - i * width * 3 - 3 * j - 3] = r;
//正面图像
rgb[i * width * 3 + 3 * j + 0] = b;
rgb[i * width * 3 + 3 * j + 1] = g;
rgb[i * width * 3 + 3 * j + 2] = r;
rgb_index++;
}
}
}
void Widget::slotOnProbeFrame(const QVideoFrame &frame)
{
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
unsigned char *rgb_buffer=new unsigned char[m_recv_w*m_recv_h*3];
if(cloneFrame.pixelFormat()==QVideoFrame::Format_YUYV)
{
yuyv_to_rgb(cloneFrame.bits(),rgb_buffer,cloneFrame.width(),cloneFrame.height());
}
else if(cloneFrame.pixelFormat()==QVideoFrame::Format_NV21)
{
NV21_TO_RGB24(cloneFrame.bits(),rgb_buffer,cloneFrame.width(),cloneFrame.height());
}
else
{
ss_log("当前摄像头格式编码为%1,暂时不支持转换.\n");
//加载图片数据
QImage image;
image.loadFromData((char *)cloneFrame.bits());
ui->widget->setImage(image);
return;
}
cloneFrame.unmap();
//加载图片数据
QImage image(rgb_buffer,
cloneFrame.width(),
cloneFrame.height(),
QImage::Format_RGB888);
ui->widget->setImage(image);
//删除数组空间
delete []rgb_buffer;
}
void Widget::ss_log(QString text)
{
QPlainTextEdit *plainTextEdit_log=ui->plainTextEdit;
//设置只读
if(!plainTextEdit_log->isReadOnly())
{
plainTextEdit_log->setReadOnly(true);
}
//设置光标到文本末尾
plainTextEdit_log->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
//当文本数量超出一定范围就清除
if(plainTextEdit_log->toPlainText().size()>1024*4)
{
plainTextEdit_log->clear();
}
plainTextEdit_log->insertPlainText(text);
//移动滚动条到底部
QScrollBar *scrollbar = plainTextEdit_log->verticalScrollBar();
if(scrollbar)
{
scrollbar->setSliderPosition(scrollbar->maximum());
}
}
void Widget::on_pushButton_update_ip_list_clicked()
{
//摄像头刷新
video_dev_list.clear();
ui->comboBox_camera->clear();
video_dev_list=QCameraInfo::availableCameras();
for(int i=0;i<video_dev_list.size();i++)
{
ui->comboBox_camera->addItem(QString("%1").arg(i));
}
}
void Widget::on_pushButton_open_clicked()
{
if(ui->pushButton_open->text()=="打开")
{
if(video_dev_list.s
没有合适的资源?快使用搜索试试~ 我知道了~
Qt移动开发-获取摄像头画面显示(完整工程).zip
共19个文件
png:4个
cpp:3个
xml:2个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
5星 · 超过95%的资源 1 下载量 107 浏览量
2023-09-12
18:49:49
上传
评论
收藏 9.09MB ZIP 举报
温馨提示
我的Qt版本: 5.12.6 资料包是一个完整的Qt工程。 实现功能: 打开当前设备的摄像头。完成摄像头画面预览。 支持Android、Windows、Linux系统,全部已经测试OK。 Android上支持前、后摄像头切换。 支持外接USB摄像头,支持设备内置摄像头。 工程里获取摄像头画面后,自己渲染显示,可以设置摄像头属性,原始画面输出尺寸。 对于拿到图像之后想要做其他处理的非常适合。
资源推荐
资源详情
资源评论
收起资源包目录
Android_Camear_Demo.zip (19个子文件)
widget.ui 2KB
widget.cpp 9KB
Android_Camear_Demo.pro 1KB
android
gradle
wrapper
gradle-wrapper.jar 53KB
gradle-wrapper.properties 205B
gradlew.bat 2KB
res
drawable-mdpi
icon.png 8KB
drawable-ldpi
icon.png 8KB
values
libs.xml 677B
drawable-hdpi
icon.png 8KB
build.gradle 2KB
gradlew 5KB
AndroidManifest.xml 7KB
Android_Camear_Demo.apk 9.09MB
main.cpp 360B
log.png 8KB
VideoShowWidget.cpp 1KB
VideoShowWidget.h 663B
widget.h 924B
共 19 条
- 1
资源评论
- jj_159561190532024-01-31资源很实用,内容详细,值得借鉴的内容很多,感谢分享。
DS小龙哥
- 粉丝: 4w+
- 资源: 522
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 2001~2022年上市公司数字赋能指数.dta
- 2001~2022年上市公司数字赋能指数.xlsx
- 信息办公石大在线财务管理系统(含源码)-shidacaiwu.rar
- 信息办公电信计费系统完整代码-netctossconformity.rar
- matlab实现TD-SCDMA中初始同步捕捉DwPTS下行同步导频时隙的仿真.zip
- 信息办公玉玺学生信息管理系统-webapps.rar
- 信息办公基于struts的图书管理系统-struts-ts.rar
- 管家婆分销ERP V1 V3 A8II TOP V10.0.2最新全版本通用
- 信息办公基于Ajax+J2EE的MicroERP源码下载-microerp-0.1.rar
- 信息办公双鱼林jsp人事工资系统-wagesmanagesystem.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功