当前位置: 首页 > news >正文

opencv+ffmpeg+QOpenGLWidget开发的音视频播放器demo

前言

    本篇文档的demo包含了 1.使用OpenCV对图像进行处理,对图像进行置灰,旋转,抠图,高斯模糊,中值滤波,部分区域清除置黑,背景移除,边缘检测等操作;2.单纯使用opencv播放显示视频;3.使用opencv和openGL播放显示视频;4.在ffmpeg解码后,使用opencv显示视频,并支持对视频的旋转翻转、裁剪、添加文字、添加logo、亮度调节、置灰、录像截图,音频开关等功能。视频播放器同时支持本地文件与网络码流地址的播放。本篇博客的最后有提供工程代码的下载。

一、OpenCV简单介绍:

    OpenCV是一个基于Apache2.0许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。应用领域包含:人机互动、物体识别、图像分割、人脸识别、动作识别、运动跟踪、机器人、运动分析、机器视觉、结构分析、汽车安全驾驶等。

二、demo调用OpenCV:

    本篇demo使用的是OpenCV-4.5.1, 是直接下载windows版本,没有额外去编译OpenCV的库,安装exe后,提取头文件和相关的库文件,用于工程调用即可。OpenCV下载路径:https://sourceforge.net/projects/opencvlibrary/

    OpenCV常用函数介绍:
    1)Mat Image = imread(filename); //从指定文件加载图像并返回
    2)namedWindow(“IMG-WIN”, cv::WINDOW_NORMAL);//创建图像显示窗口
    3)destroyWindow(“IMG-WIN”);//销毁图像显示窗口
    4)imshow(“IMG-WIN”, Image);//将图片显示在窗口中
    5)imwrite将图像保存到指定文件
    6)其他

三、demo功能介绍:

3.1.图像操作

在这里插入图片描述
    图像操作包含了显示原图、置灰、旋转、抠图、高斯模糊、中值滤波,部分区域清除置黑,背景移除,边缘检测等操作。点击显示原图后,通过点击其他按钮,可以实现图像的不同效果,例如置灰:
在这里插入图片描述
    其他功能可下载demo进行操作,点击显示原图,可恢复到之前图片显示,点击保存图片按钮可将处理后的图片进行保存。

3.2.图像操作相关代码

//图像操作
/
void MainWindow::on_pushButton_showImage_clicked()
{// load image using opencvm_srcImage = imread("./Image/test1.jpg");std::string winName = "Display window";namedWindow(winName, WINDOW_AUTOSIZE);imshow(winName, m_srcImage);if(m_bShowImage == false){HWND hwnd = static_cast<HWND>(cvGetWindowHandle(winName.c_str()));HWND parent = GetParent(hwnd);//得到nameWindow窗口的父句柄SetParent(hwnd, (HWND)ui->widget_image->winId());//设置ui控件的句柄是父句柄ShowWindow(parent, SW_HIDE);//隐藏掉nameWindow窗口resizeWindow(winName, cv::Size(ui->widget_image->width(), ui->widget_image->height()));}m_destImage = m_srcImage;m_bShowImage = true;
}void MainWindow::on_pushButton_saveImage_clicked()
{if(m_bShowImage){std::string saveFile = "./Image/test-new.jpg";if(imwrite(saveFile, m_destImage)){QMessageBox::information(this, "myOpencv", "Save Image Success.");}else{QMessageBox::critical(this, "myOpencv", "Save Image Failed.");}}elseQMessageBox::critical(this, "myOpencv", "Please click on the Show Original Image button first.");
}void MainWindow::on_pushButton_gray_clicked()
{if(m_bShowImage){cvtColor(m_srcImage, m_destImage, COLOR_BGR2GRAY);std::string winName = "Display window";namedWindow(winName, WINDOW_AUTOSIZE);imshow(winName, m_destImage);}elseQMessageBox::critical(this, "myOpencv", "Please click on the Show Original Image button first.");
}void MainWindow::on_pushButton_rotate_clicked()
{if(m_bShowImage){warpAffine(m_srcImage, m_destImage, getRotationMatrix2D({m_srcImage.cols/2.0f, m_srcImage.rows/2.0f},45,0.5),m_srcImage.size(),cv::INTER_LINEAR, cv::BORDER_CONSTANT, {255,0,0});std::string winName = "Display window";namedWindow(winName, WINDOW_AUTOSIZE);imshow(winName, m_destImage);}elseQMessageBox::critical(this, "myOpencv", "Please click on the Show Original Image button first.");
}void MainWindow::on_pushButton_matting_clicked()
{if(m_bShowImage){m_destImage = m_srcImage({20, 20, 60, 60}).clone();std::string winName = "Display window";namedWindow(winName, WINDOW_AUTOSIZE);imshow(winName, m_destImage);}elseQMessageBox::critical(this, "myOpencv", "Please click on the Show Original Image button first.");
}void MainWindow::on_pushButton_gauss_clicked()
{if(m_bShowImage){GaussianBlur(m_srcImage, m_destImage, cv::Size(5,5), 0);std::string winName = "Display window";namedWindow(winName, WINDOW_AUTOSIZE);imshow(winName, m_destImage);}elseQMessageBox::critical(this, "myOpencv", "Please click on the Show Original Image button first.");
}void MainWindow::on_pushButton_median_clicked()
{if(m_bShowImage){medianBlur(m_srcImage, m_destImage, 5);std::string winName = "Display window";namedWindow(winName, WINDOW_AUTOSIZE);imshow(winName, m_destImage);}elseQMessageBox::critical(this, "myOpencv", "Please click on the Show Original Image button first.");
}void MainWindow::on_pushButton_clear_clicked()
{if(m_bShowImage){cv::Rect roi(40, 40, 80, 80);Mat roiMat = m_destImage(roi);roiMat.setTo(cv::Scalar(0,0,0));std::string winName = "Display window";namedWindow(winName, WINDOW_AUTOSIZE);imshow(winName, m_destImage);}elseQMessageBox::critical(this, "myOpencv", "Please click on the Show Original Image button first.");
}void MainWindow::on_pushButton_clearBackground_clicked()
{//原图Mat image = imread("./Image/test1.jpg");// 创建一个掩码(mask),用于指定哪些区域是前景,哪些区域是背景cv::Mat mask(image.size(), CV_8UC1, cv::Scalar(cv::GC_BGD));cv::Rect rectangle(50, 50, image.cols - 100, image.rows - 100);cv::grabCut(image, mask, rectangle, cv::Mat(), cv::Mat(), 5, cv::GC_INIT_WITH_RECT);// 将掩码中被标记为前景的像素设为白色,背景设为黑色cv::Mat foregroundMask = (mask == cv::GC_PR_FGD) | (mask == cv::GC_FGD);cv::Mat foregroundImage(image.size(), CV_8UC3, cv::Scalar(0, 0, 0));image.copyTo(foregroundImage, foregroundMask);// 显示结果图像cv::imshow("Foreground", foregroundImage);cv::waitKey(0);
}void MainWindow::on_pushButton_edgeDetection_clicked()
{// 读取图片cv::Mat image = cv::imread("./Image/test1.jpg", cv::IMREAD_GRAYSCALE);// 边缘检测cv::Mat edges;cv::Canny(image, edges, 100, 200);// 显示结果cv::imshow("Edges", edges);cv::waitKey(0);
}

3.3.视频操作

在这里插入图片描述

    代码中通过宏定义可以旋转不同的视频处理方式(默认使用ffmpeg解码后,opencv播放显示视频),如下:

#define OPENCV_PLAY_VIDEO                   0   //单纯使用opencv播放显示视频
#define OPENCV_OPENGL_PLAY_VIDEO            0   //使用opencv和openGL播放显示视频
#define OPENCV_FFMPEG_PLAY_VIDEO            1   //使用ffmpeg解码后,opencv显示视频

    播放器支持对视频的旋转翻转、裁剪、添加文字、添加logo、亮度调节、置灰、录像截图,音频开关等功能,同时支持本地文件与网络码流地址的播放。

    简单演示如下:
在这里插入图片描述

    对原视频进行相关处理后,可通过点击录像截图按钮进行视频与图片的保存。通过开关音频按钮,支持对音频的播放处理。

    demo工程中有提供测试视频和测试logo,可以进行添加测试。
在这里插入图片描述

3.4.视频操作部分代码

void MainWindow::on_pushButton_Open_clicked()
{QString sFileName = QFileDialog::getOpenFileName(this, QString::fromLocal8Bit("Select Video File"));if(sFileName.isEmpty()){QMessageBox::critical(this, "myOpencv", QObject::tr("错误:文件不能为空."));return;}ui->lineEdit_url->setText(sFileName);
}void MainWindow::on_pushButton_Play_clicked()
{QString sStreamAddr = ui->lineEdit_url->text();if(sStreamAddr.isEmpty()){QMessageBox::critical(this, "myOpencv", QObject::tr("错误:码流地址不能为空."));return;}#if OPENCV_FFMPEG_PLAY_VIDEOif(nullptr == m_pMediaThread){MY_DEBUG << "new MediaThread";m_pMediaThread = new MediaThread(ui->openGLWidget);}else{if(m_pMediaThread->isRunning()){QMessageBox::critical(this, "myOpencv", "错误:请先点击停止按钮关闭视频.");return;}}bool bMediaInit = m_pMediaThread->Init(sStreamAddr);if(bMediaInit){m_pMediaThread->startThread();}#elif OPENCV_PLAY_VIDEOif(m_pOpencvPlayThread1 == nullptr){m_pOpencvPlayThread1 = new COpencvPlayThread1(ui->openGLWidget, sStreamAddr);}m_pOpencvPlayThread1->startThread();#elif OPENCV_OPENGL_PLAY_VIDEOif(m_pOpencvPlayThread2 == nullptr){m_pOpencvPlayThread2 = new COpencvPlayThread2(ui->openGLWidget, sStreamAddr);}m_pOpencvPlayThread2->startThread();#endif}void MainWindow::on_pushButton_Stop_clicked()
{
#if OPENCV_PLAY_VIDEOif(m_pOpencvPlayThread1)m_pOpencvPlayThread1->stopThread();
#endif#if OPENCV_OPENGL_PLAY_VIDEOif(m_pOpencvPlayThread2)m_pOpencvPlayThread2->stopThread();
#endif#if OPENCV_FFMPEG_PLAY_VIDEOif(m_pMediaThread){disconnect(m_pMediaThread, SIGNAL(sig_emitImage(const QImage&)),ui->openGLWidget, SLOT(slot_showImage(const QImage&)));m_pMediaThread->stopThread();m_pMediaThread->quit();m_pMediaThread->wait();m_pMediaThread->DeInit();}
#endif}void MainWindow::on_pushButton_startRecord_clicked()
{if(m_pMediaThread)m_pMediaThread->startRecord();
}void MainWindow::on_pushButton_stopRecord_clicked()
{if(m_pMediaThread){m_pMediaThread->stopRecord();QDesktopServices::openUrl(QUrl::fromLocalFile(RECORD_DEFAULT_PATH));}
}void MainWindow::on_pushButton_snapshot_clicked()
{if(m_pMediaThread){m_pMediaThread->Snapshot();QDesktopServices::openUrl(QUrl::fromLocalFile(SNAPSHOT_DEFAULT_PATH));}
}void MainWindow::on_pushButton_video_rotate_clicked()
{if(m_pMediaThread){int nRotate = ui->comboBox_rotate->currentIndex() - 1;if(nRotate < 0)m_pMediaThread->setRotate(false, nRotate);elsem_pMediaThread->setRotate(true, nRotate);}
}void MainWindow::on_pushButton_video_overturn_clicked()
{if(m_pMediaThread){int nOverturn = ui->comboBox_overturn->currentIndex() - 1;if(nOverturn < 0)m_pMediaThread->setFlip(false, nOverturn);elsem_pMediaThread->setFlip(true, nOverturn);}
}bool bGrey = false;
void MainWindow::on_pushButton_video_grey_clicked()
{if(m_pMediaThread){if(bGrey){m_pMediaThread->setGray(false);bGrey = false;}else{m_pMediaThread->setGray(true);bGrey = true;}}
}void MainWindow::on_pushButton_video_cropping_clicked()
{if(m_pMediaThread){int x = ui->lineEdit_crop_X->text().toInt();int y = ui->lineEdit_crop_Y->text().toInt();int w = ui->lineEdit_crop_W->text().toInt();int h = ui->lineEdit_crop_H->text().toInt();m_pMediaThread->setCrop(true, x, y, w, h);}
}void MainWindow::on_pushButton_video_addText_clicked()
{if(m_pMediaThread){int x = ui->lineEdit_text_X->text().toInt();int y = ui->lineEdit_text_Y->text().toInt();int nColor = ui->comboBox_text_rgb->currentIndex();double size = ui->comboBox_text_fonsize->currentText().toDouble();QString sText = ui->lineEdit_videoText->text();MY_DEBUG << "size:" << size;m_pMediaThread->setAddText(true, sText, x, y, nColor, size);}
}void MainWindow::on_pushButton_logoPath_clicked()
{QString sFileName = QFileDialog::getOpenFileName(this, QString::fromLocal8Bit("Select Logo File"));if(sFileName.isEmpty()){QMessageBox::critical(this, "myOpenCV", QObject::tr("错误:文件不能为空."));return;}ui->lineEdit_logo_path->setText(sFileName);
}void MainWindow::on_pushButton_addLogo_clicked()
{if(m_pMediaThread){int x = ui->lineEdit_logo_X->text().toInt();int y = ui->lineEdit_logo_Y->text().toInt();QString sAddLogoPath = ui->lineEdit_logo_path->text();m_pMediaThread->setAddLogo(true, x, y, sAddLogoPath);}
}void MainWindow::on_pushButton_setBrightness_clicked()
{if(m_pMediaThread){double brightness = ui->comboBox_brightnessVal->currentText().toDouble();m_pMediaThread->setImagePara(brightness);}
}void MainWindow::on_pushButton_restore_clicked()
{if(m_pMediaThread){int x = ui->lineEdit_crop_X->text().toInt();int y = ui->lineEdit_crop_Y->text().toInt();int w = ui->lineEdit_crop_W->text().toInt();int h = ui->lineEdit_crop_H->text().toInt();m_pMediaThread->setCrop(false, x, y, w, h);}
}void MainWindow::on_pushButto_video_deleteText_clicked()
{if(m_pMediaThread){int x = ui->lineEdit_text_X->text().toInt();int y = ui->lineEdit_text_Y->text().toInt();int nColor = ui->comboBox_text_rgb->currentIndex();double size = ui->comboBox_text_rgb->currentText().toDouble();QString sText = ui->lineEdit_videoText->text();m_pMediaThread->setAddText(false, sText, x, y, nColor, size);}
}void MainWindow::on_pushButton_deleteLogo_clicked()
{if(m_pMediaThread){int x = ui->lineEdit_logo_X->text().toInt();int y = ui->lineEdit_logo_Y->text().toInt();QString sAddLogoPath = ui->lineEdit_logo_path->text();m_pMediaThread->setAddLogo(false, x, y, sAddLogoPath);}
}void MainWindow::on_pushButton_audioOpen_clicked()
{ctAudioPlayer::getInstance().isPlay(true);
}void MainWindow::on_pushButton_audioClose_clicked()
{ctAudioPlayer::getInstance().isPlay(false);
}
void ctFFmpeg::dealWithOpenCV(AVFrame *pFrame/*, int time*/)
{if(!m_bQuit){cv::Mat destCvMat(cv::Size(m_nVideoW, m_nVideoH), CV_8UC3, cv::Scalar(1, 2, 3));destCvMat.data = (uchar*)pFrame->data[0];//旋转if(m_bRotate){MY_DEBUG << "Set Rotate m_nRotate:" << m_nRotate;rotate(destCvMat, destCvMat, m_nRotate);}//翻转if(m_bFlip){MY_DEBUG << "Set Flip";flip(destCvMat, destCvMat, m_nFlip);}//裁剪if(m_bCrop){destCvMat = destCvMat(Rect(m_nCropX, m_nCropY, m_nCropW, m_nCropH));}//灰度if(m_bGray){MY_DEBUG << "Set Gray";cvtColor(destCvMat, destCvMat, COLOR_BGR2GRAY);}//添加文字if(m_bAddText){MY_DEBUG << "m_nAddTextX:" << m_nAddTextX << ", m_nAddTextY:" << m_nAddTextY << ",m_nAddTextSize:" << m_nAddTextSize;cv::Point ptPos(m_nAddTextX, m_nAddTextY);int fontFace = cv::FONT_HERSHEY_COMPLEX;double fontScale = m_nAddTextSize;int thickness = 2;cv::Scalar color;switch(m_nAddTextColor){case ADD_TEXT_COLOR_TYPE_BLUE:color[0]=255; color[1]=0; color[2]=0;cv::putText(destCvMat, m_sAddText.toStdString(), ptPos, fontFace, fontScale, color, thickness);break;case ADD_TEXT_COLOR_TYPE_GREEN:color[0]=0; color[1]=255; color[2]=0;cv::putText(destCvMat, m_sAddText.toStdString(), ptPos, fontFace, fontScale, color, thickness);break;case ADD_TEXT_COLOR_TYPE_RED:default:color[0]=0; color[1]=0; color[2]=255;//红色cv::putText(destCvMat, m_sAddText.toStdString(), ptPos, fontFace, fontScale, color, thickness);break;}}//添加logoif(m_bAddLogo){cv::Mat logoImage = cv::imread(m_sAddLogoPath.toStdString());cv::Mat roi = destCvMat(cv::Rect(m_nAddLogoX, m_nAddLogoY, logoImage.cols, logoImage.rows));cv::addWeighted(roi, 0.5, logoImage, 0.5, 0, roi);}//亮度\暗度cv::addWeighted(destCvMat, m_nBrightness, cv::Scalar(0, 0, 0), 0, 0, destCvMat);#if OPENCV_NAME_WINDOW_SHOWcv::imshow(m_sWinName.toStdString(), destCvMat);
#endif//效率太慢, 容易导致崩溃, 不适合转QImage再用openGL播放//...//emit sig_getImage(image);//截图if(m_bSnapshot){cv::cvtColor(destCvMat, destCvMat, cv::COLOR_BGR2RGB);QImage image(destCvMat.data, destCvMat.cols, destCvMat.rows, static_cast<int>(destCvMat.step), QImage::Format_RGB888);QPixmap pixPicture = QPixmap::fromImage(image);QString sPath = "./snapshot/";QDate date = QDate::currentDate();QTime time = QTime::currentTime();m_sSnapPath = QString("%1%2-%3-%4-%5%6%7.jpg").arg(sPath).arg(date.year()). \arg(date.month()).arg(date.day()).arg(time.hour()).arg(time.minute()). \arg(time.second());MY_DEBUG << "Snapshot... m_sSnapPath:" << m_sSnapPath;pixPicture.save(m_sSnapPath, "jpg");m_bSnapshot = false;}}
}

四、工程源码下载:

demo播放器下载:https://download.csdn.net/download/linyibin_123/88217460

demo播放器工程源码下载:https://download.csdn.net/download/linyibin_123/88217472

相关文章:

opencv+ffmpeg+QOpenGLWidget开发的音视频播放器demo

前言 本篇文档的demo包含了 1.使用OpenCV对图像进行处理&#xff0c;对图像进行置灰&#xff0c;旋转&#xff0c;抠图&#xff0c;高斯模糊&#xff0c;中值滤波&#xff0c;部分区域清除置黑&#xff0c;背景移除&#xff0c;边缘检测等操作&#xff1b;2.单纯使用opencv播放…...

stable-diffusion-webui 的模型更新

shared.py和sd_models.py中 shared.py: options_templates.update(options_section((sd, "Stable Diffusion"), {"sd_model_checkpoint": OptionInfo(None, "Stable Diffusion checkpoint", gr.Dropdown, lambda: {"choices": list_…...

Gin模板语法

Gin模板语法 文章目录 <center> Gin模板语法前提提醒Gin框架启动服务器模板解析模板渲染遇到不同目录下相同的文件如何加载和渲染自定义函数加载静态文件 前提提醒 由于有了前面template包的基础,所以该笔记不再过多详细分析 Gin框架启动服务器 语法: r:gin.Default()/…...

Go http.Handle和http.HandleFunc的路由问题

Golang的net/http包提供了原生的http服务&#xff0c;其中http.Handle和http.HandleFunc是两个重要的路由函数。 1. 函数介绍 http.HandleFunc和http.Handle的函数原型如下&#xff0c;其中DefaultServeMux是http包提供的一个默认的路由选择器。 func HandleFunc(pattern st…...

如何使用Kali Linux进行渗透测试?

1. 渗透测试简介 渗透测试是通过模拟恶意攻击&#xff0c;评估系统、应用或网络的安全性的过程。Kali Linux为渗透测试人员提供了丰富的工具和资源&#xff0c;用于发现漏洞、弱点和安全风险。 2. 使用Kali Linux进行渗透测试的步骤 以下是使用Kali Linux进行渗透测试的基本…...

简单易用且高效的跨平台开发工具:Xojo 2023 for Mac

Xojo for Mac是Mac平台上一个跨平台的针对桌面、Web、移动和Raspberry Pi的快速应用程序开发软件。与其他多平台开发工具相比&#xff0c;Xojo for Mac为开发人员提供了显着的生产率提高。 Xojo for Mac具有拖放功能&#xff0c;使您能够快速创建用户界面设计&#xff0c;然后…...

HIVE SQL实现分组字符串拼接concat

在Mysql中可以通过group_concat()函数实现分组字符串拼接&#xff0c;在HIVE SQL中可以使用concat_ws()collect_set()/collect_list()函数实现相同的效果。 实例&#xff1a; abc2014B92015A82014A102015B72014B6 1.concat_wscollect_list 非去重拼接 select a ,concat_ws(-…...

【问心篇】渴望、热情和选择

加班太严重完全没有时间学习&#xff0c;怎么办&#xff1f; 我真的不算聪明的人&#xff0c;但是&#xff0c;我对学习真的是有渴望的。说得好听一点&#xff0c;我希望自己在不停地成长&#xff0c;不辜负生活在这个信息化大变革的时代。说得不好的一点&#xff0c;就是我从…...

【贪心】CF1841 D

Codeforces 题意&#xff1a; 思路&#xff1a; 首先模拟一下样例 并没有发现什么 那么就去考虑特殊情况&#xff0c;看看有没有什么启发 考虑一个大区间包含所有小区间的情形&#xff0c;这种情况就是在这么多区间中找出两个区间 换句话说&#xff0c;这么多区间组成一个…...

移动端预览指定链接的pdf文件流

场景 直接展示外部系统返回的获取文件流时出现了跨域问题&#xff1a; 解决办法 1. 外部系统返回的请求头中调整&#xff08;但是其他系统不会给你改的&#xff09; 2. 我们系统后台获取文件流并转为新的文件流提供给前端 /** 获取传入url文件流 */ GetMapping("/get…...

【Go 基础篇】Go语言字符类型:解析字符的本质与应用

介绍 字符类型是计算机编程中用于表示文本和字符的数据类型&#xff0c;是构建字符串的基本单位。在Go语言&#xff08;Golang&#xff09;中&#xff0c;字符类型具有独特的特点和表示方式&#xff0c;包括Unicode编码、字符字面值以及字符操作。本篇博客将深入探讨Go语言中的…...

Java基础(十二)面向对象编程 OOP

一、抽象数据类型 1.面向对象基本概念 1. 面向对象 面向对象程序设计&#xff08;OOP&#xff09;是一种基于对象概念的软件开发方法&#xff0c;是目前软件开发的主流方式。 常见面向对象的语言&#xff1a;C 、Python 、Java 常见面向过程的语言&#xff1a;C 面向对象的三…...

在阿里云服务器上安装Microsoft SharePoint 2016流程

本教程阿里云百科分享如何在阿里云ECS上搭建Microsoft SharePoint 2016。Microsoft SharePoint是Microsoft SharePoint Portal Server的简称。SharePoint Portal Server是一个门户站点&#xff0c;使得企业能够开发出智能的门户站点。 目录 背景信息 步骤一&#xff1a;添加…...

Ubuntu设置定时重启

1.安装/更新 cron 安装crontab sudo apt-get install cron更新命令 sudo apt-get update2.配置cron定时任务 sudo nano /etc/crontab* * * * * root reboot(从左到右&#xff0c;五个 * 依次是 分&#xff0c;时 &#xff0c;天&#xff0c;月&#xff0c;星期)下列命令表示…...

sqlloader学习笔记

INFILE的用法 1&#xff09;模糊导入多个数据的文件。 可以在文件名中使用通配符。 星号 &#xff08;*&#xff09; 表示复数字符&#xff0c;问号 &#xff08;&#xff1f;&#xff09; 表示单个字符。 INFILE emp*.dat INFILE m?emp.dat 2&#xff09;如果不需要导入数据…...

内网ip与外网ip

一、关于IP地址 我们平时直接接触最多的是内网IP。而且还可以自己手动修改ip地址。而外网ip&#xff0c;我们很少直接接触&#xff0c;都是间接接触、因为外网ip一般都是运营商管理&#xff0c;而且是全球唯一的&#xff0c;一般我们自己是无法修改的。 内网IP和外网IP是指在…...

分布式 - 消息队列Kafka:Kafka消费者和消费者组

文章目录 1. Kafka 消费者是什么&#xff1f;2. Kafka 消费者组的概念&#xff1f;3. Kafka 消费者和消费者组有什么关系&#xff1f;4. Kafka 多个消费者如何同时消费一个分区&#xff1f; 1. Kafka 消费者是什么&#xff1f; 消费者负责订阅Kafka中的主题&#xff0c;并且从…...

feign调用和被调用者字段名称不对应解决

如果您在使用Feign时&#xff0c;尝试使用SerializedName("id")或JsonAlias("id")修饰字段&#xff0c;但仍然无法正常生效&#xff0c;可能是由于以下原因&#xff1a; Feign不会直接使用Gson库进行序列化和反序列化&#xff0c;而是使用了默认的Jackson库…...

【UE4 RTS】07-Camera Boundaries

前言 本篇实现的效果是当CameraPawn移动到地图边缘时会被阻挡。 效果 步骤 1. 打开项目设置&#xff0c;在“引擎-碰撞”中&#xff0c;点击“新建Object通道” 新建通道命名为“MapBoundaries”&#xff0c;然后点击接受 2. 向视口中添加 阻挡体积 调整阻挡体积的缩放 向四…...

大语言模型之二 GPT发展史简介

得益于数据、模型结构以及并行算力的发展&#xff0c;大语言模型应用现今呈井喷式发展态势&#xff0c;大语言神经网络模型成为了不可忽视的一项技术。 GPT在自然语言处理NLP任务上取得了突破性的进展&#xff0c;扩散模型已经拥有了成为下一代图像生成模型的代表的潜力&#x…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

AI书签管理工具开发全记录(十九):嵌入资源处理

1.前言 &#x1f4dd; 在上一篇文章中&#xff0c;我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源&#xff0c;方便后续将资源打包到一个可执行文件中。 2.embed介绍 &#x1f3af; Go 1.16 引入了革命性的 embed 包&#xff0c;彻底改变了静态资源管理的…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

C++使用 new 来创建动态数组

问题&#xff1a; 不能使用变量定义数组大小 原因&#xff1a; 这是因为数组在内存中是连续存储的&#xff0c;编译器需要在编译阶段就确定数组的大小&#xff0c;以便正确地分配内存空间。如果允许使用变量来定义数组的大小&#xff0c;那么编译器就无法在编译时确定数组的大…...

Ubuntu Cursor升级成v1.0

0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开&#xff0c;快捷键也不好用&#xff0c;当看到 Cursor 升级后&#xff0c;还是蛮高兴的 1. 下载 Cursor 下载地址&#xff1a;https://www.cursor.com/cn/downloads 点击下载 Linux (x64) &#xff0c;…...

DAY 26 函数专题1

函数定义与参数知识点回顾&#xff1a;1. 函数的定义2. 变量作用域&#xff1a;局部变量和全局变量3. 函数的参数类型&#xff1a;位置参数、默认参数、不定参数4. 传递参数的手段&#xff1a;关键词参数5 题目1&#xff1a;计算圆的面积 任务&#xff1a; 编写一…...