Linux系统USB摄像头测试程序(三)_视频预览

这是在linux上usb摄像头视频预览程序,此程序用到了ffmpeg、sdl2、gtk3组件,程序编译之前应先安装他们。

#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <zconf.h>
#include <linux/videodev2.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <gtk-3.0/gtk/gtk.h>#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
#include "libavutil/imgutils.h"
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersrc.h>
#include <libavfilter/buffersink.h>#include <SDL2/SDL.h>//dhl:gtk窗口组件
GtkWidget *window;
GtkWidget *fixed;
GtkWidget *button1,*button2,*button3;
GtkWidget *text,*text1,*text2,*text3;
GtkTextBuffer *buffer,*buffer1,*buffer2,*buffer3;
GtkWidget *label1,*label2,*label3,*label_line;//dhl:sdl窗口组件
SDL_Window *sdl_window; 
SDL_Renderer *sdl_renderer;
SDL_Texture *sdl_texture;//dhl:消息缓存
char disp[2048]={0};
char temp[128]={0};int getWHR(char *device_name,char *win_size,int *win_width,int *win_height, char *frame_rate_t)
{GtkTextIter start,end;gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buffer1),&start,&end);GtkTextIter s=start,e=end;sprintf(device_name,"%s",gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer1),&s,&e,FALSE));gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buffer2),&start,&end);s=start,e=end;gchar *win_size1 = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer2),&s,&e,FALSE);sprintf(win_size,"%s",gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer2),&s,&e,FALSE));gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buffer3),&start,&end);s=start,e=end;sprintf(frame_rate_t,"%s",gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer3),&s,&e,FALSE));if (!strcmp(device_name,"")|| !strcmp(win_size,"")||!strcmp(frame_rate_t,"")) {GtkWidget * dialog= dialog = gtk_message_dialog_new (NULL,GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_INFO,GTK_BUTTONS_CLOSE,"请输入摄像头设备名称、窗口尺寸、帧速率");gtk_dialog_run (GTK_DIALOG (dialog));gtk_widget_destroy (dialog);return -1;}sscanf(win_size1, "%dx%d", win_width, win_height);return 0;
}//dhl:发现摄像头
void button1_clicked(GtkWidget *widget, gpointer data)
{char camera_devices_name[128]={0};for (int loop=0;loop<10;loop++) {sprintf(camera_devices_name,"/dev/video%d",loop);int fd = open(camera_devices_name, O_RDWR);if(fd < 0){printf("打开设备失败(%s)\n",camera_devices_name);close(fd);continue;}close(fd);sprintf(temp,"发现摄像头:%s\n",camera_devices_name);strcat(disp,temp);gtk_text_buffer_set_text(buffer,disp,-1);}sprintf(disp,"%s","");
}//dhl:查询配置信息
void button2_clicked(GtkWidget *widget, gpointer data)
{int line_num=0;gchar *device_name;GtkTextIter start,end;gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(buffer1),&start,&end);const GtkTextIter s=start,e=end;device_name=gtk_text_buffer_get_text(GTK_TEXT_BUFFER(buffer1),&s,&e,FALSE);if (!strcmp(device_name,"")){sprintf(temp,"请输入摄像头设备文件名\n");strcat(disp,temp);gtk_text_buffer_set_text(buffer,disp,-1);sprintf(disp,"%s","");return;}//dhl:查询摄像头支持的视频格式int fd = open(device_name, O_RDWR);if(fd < 0){printf("打开设备失败\n");return;}struct v4l2_fmtdesc v4fmt;v4fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //视频捕获设备int i=0;while(1){v4fmt.index = i++;int ret = ioctl(fd, VIDIOC_ENUM_FMT, &v4fmt);if(ret < 0){printf("获取摄像头格式失败");break;}printf("index=%d\n", v4fmt.index);printf("flags=%d\n", v4fmt.flags);printf("description=%s\n", v4fmt.description);unsigned char *p = (unsigned char *)&v4fmt.pixelformat;printf("pixelformat=%c%c%c%c\n", p[0],p[1],p[2],p[3]);printf("reserved=%d\n", v4fmt.reserved[0]);sprintf(temp,"摄像头支持的视频格式(%d)\n",i);strcat(disp,temp);sprintf(temp,"index=%d,", v4fmt.index);strcat(disp,temp);sprintf(temp,"flags=%d,", v4fmt.flags);strcat(disp,temp);sprintf(temp,"description=%s,", v4fmt.description);strcat(disp,temp);sprintf(temp,"pixelformat=%c%c%c%c,", p[0],p[1],p[2],p[3]);strcat(disp,temp);sprintf(temp,"reserved=%d\n", v4fmt.reserved[0]);strcat(disp,temp);}close(fd);//dhl:MJPG支持的所有分辨率如下fd = open(device_name, O_RDWR);if(fd < 0){perror("打开设备失败");return;}struct v4l2_frmsizeenum frmsize;frmsize.index = 0;frmsize.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;printf("MJPEG格式支持所有分辨率如下:\n");//frmsize.pixel_format = V4L2_PIX_FMT_YUYV;frmsize.pixel_format = V4L2_PIX_FMT_MJPEG;sprintf(temp,"MJPG支持的分辨率:\n");strcat(disp,temp);line_num=1;while(ioctl(fd,VIDIOC_ENUM_FRAMESIZES,&frmsize) == 0){printf("frame_size<%d*%d>\n",frmsize.discrete.width,frmsize.discrete.height);frmsize.index++;if ((line_num % 5) != 0) { sprintf(temp,"MJPEG frame_size<%d*%d>, ",frmsize.discrete.width,frmsize.discrete.height);}else {sprintf(temp,"MJPEG frame_size<%d*%d>\n",frmsize.discrete.width,frmsize.discrete.height);}strcat(disp,temp);line_num++;if (line_num == 6) {line_num = 1;}}close(fd);sprintf(temp,"%s","\n");strcat(disp,temp);//dhl:YUV支持所有分辨率如下fd = open(device_name, O_RDWR);if(fd < 0){perror("打开设备失败");return;}//struct v4l2_frmsizeenum frmsize;frmsize.index = 0;frmsize.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;printf("MJPEG格式支持所有分辨率如下:\n");frmsize.pixel_format = V4L2_PIX_FMT_YUYV;//frmsize.pixel_format = V4L2_PIX_FMT_MJPEG;sprintf(temp,"YUV支持的分辨率:\n");strcat(disp,temp);line_num = 1;while(ioctl(fd,VIDIOC_ENUM_FRAMESIZES,&frmsize) == 0){printf("frame_size<%d*%d>\n",frmsize.discrete.width,frmsize.discrete.height);frmsize.index++;if ((line_num % 5) != 0) { sprintf(temp,"YUYV frame_size<%d*%d>, ",frmsize.discrete.width,frmsize.discrete.height);}else {sprintf(temp,"YUYV frame_size<%d*%d>\n",frmsize.discrete.width,frmsize.discrete.height);}strcat(disp,temp);line_num++;if (line_num == 6) {line_num = 1;}}close(fd);gtk_text_buffer_set_text(buffer,disp,-1);sprintf(disp,"%s","");}//dhl:视频预览
void button3_clicked(GtkWidget *widget, gpointer data)
{AVFormatContext *pFormatCtx;int             i, videoindex;AVCodecContext  *pCodecCtx;AVCodec         *pCodec;int ret = -1;int win_width=0, win_height=0;gchar device_name[128];gchar win_size[128];gchar frame_rate_t[128];int iRet=getWHR(device_name,win_size,&win_width,&win_height, frame_rate_t);if (iRet!=0) {return;}const char * out_path = "out_yuyv422.yuv";FILE* outFile = fopen(out_path, "wb");if (!outFile) {printf("Could not open %s\n", out_path);return;}if (SDL_Init(SDL_INIT_VIDEO)) {printf("Could not initialize SDL - %s\n", SDL_GetError());return;}else{printf("initialize SDL ok\n");}sdl_window = SDL_CreateWindow("视频预览",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,win_width,win_height,SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE);if(sdl_window == NULL){printf("SDL_window创建失败\n");return;}sdl_renderer = SDL_CreateRenderer(sdl_window,-1,SDL_RENDERER_ACCELERATED);sdl_texture = SDL_CreateTexture(sdl_renderer//,SDL_PIXELFORMAT_IYUV,SDL_PIXELFORMAT_YUY2,SDL_TEXTUREACCESS_TARGET,win_width,win_height);SDL_Rect sdl_rect;char *buffer_pixels = malloc(win_width*win_height*4);pFormatCtx = avformat_alloc_context();const AVInputFormat *ifmt = av_find_input_format("v4l2");AVDictionary *option =NULL;av_dict_set(&option,"video_size",win_size,0);av_dict_set(&option,"framerate",frame_rate_t,0);//av_dict_set(&option,"pixel_format","yuv420p12be",0); //指定格式avformat_open_input(&pFormatCtx, device_name, ifmt,&option);if(avformat_find_stream_info(pFormatCtx, NULL) < 0){printf("Couldn't find stream information.\n");return;}videoindex = -1;for(i = 0; i < pFormatCtx->nb_streams; i++){if(pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){videoindex = i;break;}}if(videoindex == -1){printf("Didn't find a video stream.\n");return;}else{printf("Find a video stream:%d.\n", videoindex);}pCodec = (AVCodec*)avcodec_find_decoder(pFormatCtx->streams[videoindex]->codecpar->codec_id);if(pCodec == NULL){printf("Codec not found.\n");return;}pCodecCtx = avcodec_alloc_context3(pCodec);avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoindex]->codecpar);printf("VideoStream:Frame.Width=%d,Height=%d\n",pCodecCtx->width, pCodecCtx->height);if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0){printf("Could not open codec.\n");return;}AVPacket *pkt = av_packet_alloc();if(!pkt){printf("av_packet_alloc错误\n");return;}AVFrame *frame_yuyv422 = av_frame_alloc();if(!frame_yuyv422){printf("av_frame_alloc错误\n");return;}int frame_count = 0;//记录获取的帧数SDL_Event event;while (av_read_frame(pFormatCtx, pkt) >= 0 ) {if(pkt->stream_index == videoindex){//dhl:发送给解码器if(avcodec_send_packet(pCodecCtx,pkt) != 0){printf("avcodec_send_packet error ...\n");break;}//dhl:从解码器中得到摄像头的原始视频帧int loop=0;while(avcodec_receive_frame(pCodecCtx,frame_yuyv422) == 0){frame_count++;for(int i = 0;i < frame_yuyv422->height;i++){memcpy(buffer_pixels+i * frame_yuyv422->linesize[0],frame_yuyv422->data[0] + i * frame_yuyv422->linesize[0],frame_yuyv422->linesize[0]);}SDL_UpdateTexture(sdl_texture,NULL,buffer_pixels,win_width*2);//dhl:将纹理数据拷贝给渲染器sdl_rect.x = 0;sdl_rect.y = 0;sdl_rect.w = win_width;sdl_rect.h = win_height;//dhl:先清空帧画面,再重新绘制SDL_RenderClear(sdl_renderer);SDL_RenderCopy(sdl_renderer,sdl_texture,NULL,&sdl_rect);//dhl:显示帧画面SDL_RenderPresent(sdl_renderer);//dhl:延时渲染//SDL_Delay(frame_rate);//延时}}av_packet_unref(pkt);for (int ll=0;ll<10;ll++) {SDL_PollEvent(&event);}	if (event.type == SDL_QUIT) {break;}}fclose(outFile);sprintf(disp,"预览总帧数:%d",frame_count);gtk_text_buffer_set_text(buffer,disp,-1);sprintf(disp,"%s","");av_free(frame_yuyv422);av_packet_free(&pkt);avformat_close_input(&pFormatCtx);free(buffer_pixels);SDL_DestroyTexture(sdl_texture);SDL_DestroyRenderer(sdl_renderer);SDL_DestroyWindow(sdl_window );		SDL_Quit();return;}int main(int argc,char *argv[])
{gtk_init(&argc,&argv);avdevice_register_all();window = gtk_window_new(GTK_WINDOW_TOPLEVEL);gtk_window_set_title(GTK_WINDOW(window),"USB摄像头测试程序(v1.0.20230728)");//gtk_window_set_resizable(GTK_WINDOW(window),FALSE);gtk_window_set_default_size(GTK_WINDOW(window),1280,800);gtk_window_set_position(GTK_WINDOW(window),GTK_WIN_POS_CENTER);fixed = gtk_fixed_new();gtk_container_add(GTK_CONTAINER(window),fixed);text = gtk_text_view_new();buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text));gtk_text_buffer_set_text(buffer,"",-1);gtk_fixed_put(GTK_FIXED(fixed),text,20,480);gtk_widget_set_size_request(text,1240,300);button1 = gtk_button_new_with_label("查询摄像头");gtk_fixed_put(GTK_FIXED(fixed),button1,320,14);gtk_widget_set_size_request(button1,100,20);label1 = gtk_label_new("摄像头:");gtk_fixed_put(GTK_FIXED(fixed),label1,440,14);gtk_widget_set_size_request(label1,50,30);text1 = gtk_text_view_new();buffer1=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text1));gtk_text_buffer_set_text(buffer1,"",-1);gtk_fixed_put(GTK_FIXED(fixed),text1,500,16);gtk_widget_set_size_request(text1,100,28);sprintf(disp,"/dev/video0");gtk_text_buffer_set_text(buffer1,disp,-1);button2 = gtk_button_new_with_label("查询配置");gtk_fixed_put(GTK_FIXED(fixed),button2,610,14);gtk_widget_set_size_request(button2,80,35);label2 = gtk_label_new("分辨率:");gtk_fixed_put(GTK_FIXED(fixed),label2,740,18);gtk_widget_set_size_request(label2,50,30);text2 = gtk_text_view_new();buffer2=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text2));gtk_text_buffer_set_text(buffer2,"",-1);gtk_fixed_put(GTK_FIXED(fixed),text2,800,16);gtk_widget_set_size_request(text2,100,28);sprintf(disp,"640x480");gtk_text_buffer_set_text(buffer2,disp,-1);label3 = gtk_label_new("帧率:");gtk_fixed_put(GTK_FIXED(fixed),label3,930,18);gtk_widget_set_size_request(label3,50,30);text3 = gtk_text_view_new();buffer3=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text3));gtk_text_buffer_set_text(buffer3,"",-1);gtk_fixed_put(GTK_FIXED(fixed),text3,980,16);gtk_widget_set_size_request(text3,100,28);sprintf(disp,"30");gtk_text_buffer_set_text(buffer3,disp,-1);label_line = gtk_label_new("______________________________________________________________________________________________________________________________");gtk_fixed_put(GTK_FIXED(fixed),label_line,320,45);gtk_widget_set_size_request(label_line,800,3);GtkWidget *labelChild;PangoFontDescription *font;int fontSize = 10;font = pango_font_description_from_string("Sans");				//"Sans"字体名pango_font_description_set_size(font, fontSize * PANGO_SCALE);	//设置字体大小labelChild = gtk_bin_get_child(GTK_WIDGET(button1));			//取出GtkButton里的labelgtk_widget_modify_font(GTK_WIDGET(labelChild), font);			//设置label的字体, 这样这个GtkButton上面显示的字体就变了labelChild = gtk_bin_get_child(GTK_WIDGET(button2));			gtk_widget_modify_font(GTK_WIDGET(labelChild), font);			button3 = gtk_button_new_with_label("视频预览");gtk_fixed_put(GTK_FIXED(fixed),button3,320,80);gtk_widget_set_size_request(button3,80,20);g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);g_signal_connect(G_OBJECT(button1), "clicked", G_CALLBACK(button1_clicked),NULL);g_signal_connect(G_OBJECT(button2), "clicked", G_CALLBACK(button2_clicked),NULL);g_signal_connect(G_OBJECT(button3), "clicked", G_CALLBACK(button3_clicked),NULL);	gtk_widget_show_all(window);gtk_main();return 0;
}

编译命令:gcc preview_camera.c  -o camera_preview `pkg-config --cflags --libs  libavdevice libavfilter libavformat  libavcodec libavutil libpostproc  libswresample  libswscale` `pkg-config --cflags --libs sdl2` `pkg-config --cflags --libs gtk+-3.0`  -w

运行截图:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/48663.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过postgresql的Ltree字段类型实现目录结构的基本操作

通过postgresql的Ltree字段类型实现目录结构的基本操作 将这种具有目录结构的excel表存储到数据库中&#xff0c;可以采用树型结构存储 DROP TABLE IF EXISTS "public"."directory_tree"; CREATE TABLE "public"."directory_tree" (…

产品流程图是什么?怎么做?

产品流程图是什么&#xff1f; 产品流程图是一种图形化的表达方式&#xff0c;用于描述产品开发、制造、销售、使用等各个阶段中涉及的流程、步骤和关系。它通过图形符号、箭头、文本等元素&#xff0c;展示了产品的各个环节之间的关联和顺序&#xff0c;通常被用于可视化产…

lwIP更新记10:IP 冲突检测

lwip-2.2.0-rc1 版本于 2023 年 6 月 29 日发布&#xff0c;带来了我期盼已久的 IPv4 冲突检测 功能。 lwip-2.2.0-rc1 版本重新回归了 master 分支&#xff08;主分支&#xff09;&#xff0c;不再使用单独的稳定分支。 master 分支 是一个 Git&#xff08;版本控制程序&…

[保研/考研机试] KY196 复数集合 北京邮电大学复试上机题 C++实现

题目链接&#xff1a; 复数集合_牛客题霸_牛客网 一个复数&#xff08;xiy&#xff09;集合&#xff0c;两种操作作用在该集合上&#xff1a; 1、Pop 表示读出集。题目来自【牛客题霸】https://www.nowcoder.com/share/jump/437195121692724009060 描述 一个复数&#xff08;…

如何做好流量经营?数字化系统如何加速流量增长

​在用户转化策略上&#xff0c;从“公域流量”到“私域流量”的来源转变&#xff0c;充分说明企业已经意识到公域流量存在成本高、粘度差、稳定性差等问题&#xff0c;开始寻求拥有更低成本、更容易培养忠实度、更容易精准触达的私域流量。但由于企业缺少整体、系统化的私域经…

深入浅出 TCP/IP 协议栈

TCP/IP 协议栈是一系列网络协议的总和&#xff0c;是构成网络通信的核心骨架&#xff0c;它定义了电子设备如何连入因特网&#xff0c;以及数据如何在它们之间进行传输。TCP/IP 协议采用4层结构&#xff0c;分别是应用层、传输层、网络层和链路层&#xff0c;每一层都呼叫它的下…

SSD基本工作原理了解

SSD与RAM的原理有些类似&#xff0c;RAM使用晶体管和电容来表示0或1&#xff0c;晶体管用于将电荷转移到电容器或从电容器中吸取电荷&#xff0c;并且电荷必须每几微秒刷新一次。 而SSD相比于RAM的非易失性来自于其使用的浮栅晶体管。其创造了一个小笼子&#xff0c;不需要外界…

适配器模式实现stack和queue

适配器模式实现stack和queue 什么是适配器模式&#xff1f;STL标准库中stack和queue的底层结构stack的模拟实现queue的模拟实现 什么是适配器模式&#xff1f; 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)&#xff…

MPP 还是主流架构吗

MPP 架构&#xff1a; MPP 架构的产品&#xff1a; Impala ClickHouse Druid Doris 很多 OLAP 引擎都采用了 MPP 架构 批处理系统 - 使用场景分钟级、小时级以上的任务&#xff0c;目前很多大型互联网公司都大规模运行这样的系统&#xff0c;稳定可靠&#xff0c;低成本。…

<深度学习基础> 激活函数

为什么需要激活函数&#xff1f;激活函数的作用&#xff1f; 激活函数可以引入非线性因素&#xff0c;可以学习到复杂的任务或函数。如果不使用激活函数&#xff0c;则输出信号仅是一个简单的线性函数。线性函数一个一级多项式&#xff0c;线性方程的复杂度有限&#xff0c;从…

如何在服务器上用kaggle下载数据集

S1 服务器上安装kaggle cli工具 pip install --user kaggleS2 服务器上创建kaggle目录 mkdir ~/.kaggleS3 进入kaggle账户创建token 生成token 点击右上角头像&#xff0c;选择setting 点击create new token 进入你的浏览器下载页&#xff0c;可以看到有了一个kaggle.jso…

【Linux操作系统】Linux系统编程中信号捕捉的实现

在Linux系统编程中&#xff0c;信号是一种重要的机制&#xff0c;用于实现进程间通信和控制。当某个事件发生时&#xff0c;如用户按下CtrlC键&#xff0c;操作系统会向进程发送一个信号&#xff0c;进程可以捕获并相应地处理该信号。本篇博客将介绍信号的分类、捕获与处理方式…

ImportError: cannot import name ‘SQLDatabaseChain‘ from ‘langchain‘解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

深度学习基本理论下篇:(梯度下降/卷积/池化/归一化/AlexNet/归一化/Dropout/卷积核)、深度学习面试

深度学习基本理论上篇&#xff1a;&#xff08;MLP/激活函数/softmax/损失函数/梯度/梯度下降/学习率/反向传播&#xff09; 深度学习基本理论上篇&#xff1a;&#xff08;MLP/激活函数/softmax/损失函数/梯度/梯度下降/学习率/反向传播&#xff09;、深度学习面试_会害羞的杨…

全国城市内涝排涝模拟技术及在市政、规划设计中应用教程

详情点击链接&#xff1a;全国城市内涝排涝模拟技术及在市政、规划设计中应用教程 一&#xff0c;数据准备 通过标准化的步骤&#xff0c;利用CAD数据、GIS数据&#xff0c;在建模的不同阶段发挥不同软件的优势&#xff0c;实现高效的数据处理、准确的参数赋值、模型的快速建…

Maven 配置文件修改及导入第三方jar包

设置java和maven的环境变量 修改maven配置文件 &#xff08;D:\app\apache-maven-3.5.0\conf\settings.xml&#xff0c;1中环境变量对应的maven包下的conf&#xff09; 修改131行左右的mirror&#xff0c;设置阿里云的仓库地址 <mirror> <id>alimaven</id&g…

无涯教程-PHP - sql_regcase()函数

sql_regcase() - 语法 string sql_regcase (string string) 可以将sql_regcase()函数视为实用程序函数&#xff0c;它将输入参数字符串中的每个字符转换为包含两个字符的带括号的表达式。 sql_regcase() - 返回值 返回带括号的表达式字符串以及转换后的字符。 sql_regcase…

[Mac软件]MacCleaner 3 PRO 3.2.1应用程序清理和卸载

应用介绍 MacCleaner PRO是一个应用程序包&#xff0c;将帮助您清除磁盘空间并加快Mac的速度&#xff01; MacCleaner PRO - 让您的Mac始终快速、干净和有条理。 App Cleaner & Uninstaller PRO - 完全删除未使用的应用程序并管理Mac扩展。 磁盘空间分析仪PRO-分析磁盘空…

PHP求职招聘系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP 求职招聘系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 源码 https://download.csdn.net/download/qq_41221322/88240283 论文 https://down…

(一)idea连接GitHub的全部流程(注册GitHub、idea集成GitHub、增加合作伙伴、跨团队合作、分支操作)

&#xff08;二&#xff09;Git在公司中团队内合作和跨团队合作和分支操作的全部流程&#xff08;一篇就够&#xff09;https://blog.csdn.net/m0_65992672/article/details/132336481 4.1、简介 Git是一个免费的、开源的*分布式**版本控制**系统*&#xff0c;可以快速高效地…