FFmpeg视频处理入门级教程
一、FFmpeg常规处理流程
文字说明:
- 初始化容器格式和编解码器
- 打开输入文件建立连接
- 解析媒体流信息(时长/分辨率/编码格式等)
- 遍历找到视频流索引
- 根据编码器ID查找对应解码器
- 初始化并配置解码器上下文
- 循环读取压缩数据包
- 判断数据包类型并解码视频帧
- 对原始帧进行格式转换或处理
- 释放所有分配的资源
二、FFmpeg核心模块解析
2.1 模块预览
FFmpeg由多个功能模块组成,以下是8个核心模块的详细说明:
模块名称 | 功能描述 | 典型应用场景 |
---|---|---|
libavcodec | 编解码库,包含主流音视频编码器的实现 | H.264解码、MP3编码、音频重采样 |
libavformat | 封装/解封装库,处理多媒体容器格式(MP4/MKV/FLV等) | 解析MP4文件头信息、将H.264流封装为TS格式 |
libavutil | 基础工具库,提供通用数据结构、数学运算等基础功能 | 时间戳计算、内存管理、日志输出 |
libswscale | 图像处理库,实现色彩空间转换和图像缩放 | YUV420转RGB24、4K视频缩放到1080p |
libavfilter | 滤镜处理库,支持多路视频流的复杂滤镜处理 | 添加水印、视频画中画、音频混音 |
libavdevice | 设备访问库,支持采集显示设备数据 | 摄像头抓取画面、屏幕录制、音频采集卡输入 |
libswresample | 音频重采样库,处理音频格式转换 | 48kHz转44.1kHz、单声道转立体声、PCM格式转换 |
libpostproc | 后处理库,提供视频后期效果处理 | 视频去块效应、MPEG视频补偿 |
模块依赖关系:
avformat → avcodec → avutil
avfilter → avformat
swscale/swresample → avutil
2.2 部分模块说明详解:
libavcodec 工作机理:
libavfilter 处理链示例:
// 创建滤镜图:视频缩放+叠加水印
filter_graph = avfilter_graph_alloc();
avfilter_graph_create_filter(&buffer_src_ctx, "输入源");
avfilter_graph_create_filter(&scale_filter, "scale=640:480");
avfilter_graph_create_filter(&overlay_filter, "overlay=10:10");
avfilter_graph_create_filter(&buffer_sink_ctx, "输出端");// 连接滤镜节点
avfilter_link(buffer_src_ctx, 0, scale_filter, 0);
avfilter_link(scale_filter, 0, overlay_filter, 0);
avfilter_link(overlay_filter, 0, buffer_sink_ctx, 0);
模块选择原则:
- 文件操作:优先使用avformat
- 编解码处理:使用avcodec
- 图像处理:使用swscale或avfilter
- 实时流采集:配合avdevice使用
三、核心API函数说明
函数名称 | 功能描述 | 关键参数说明 |
---|---|---|
av_register_all() | 注册所有封装格式与编解码器(新版本已弃用) | 无参数 |
avformat_open_input() | 打开媒体文件并初始化AVFormatContext | ps: 上下文指针地址 url: 文件路径 fmt: 强制指定格式(可NULL) |
avformat_find_stream_info() | 获取媒体流详细信息 | ic: 上下文指针 options: 额外选项(通常NULL) |
avcodec_find_decoder() | 根据编码ID查找解码器 | id: 编码格式ID(如AV_CODEC_ID_H264) |
avcodec_open2() | 打开解码器 | avctx: 解码器上下文 codec: 解码器指针 options: 额外参数 |
av_read_frame() | 读取媒体文件中的数据包 | s: 上下文指针 pkt: 输出的数据包 |
avcodec_send_packet() | 发送压缩数据到解码器 | avctx: 解码器上下文 avpkt: 输入数据包 |
avcodec_receive_frame() | 从解码器获取解码后的帧 | avctx: 解码器上下文 frame: 输出的原始帧 |
sws_getContext() | 初始化图像缩放转换上下文 | 参数包含源/目标分辨率、格式等图像特征 |
sws_scale() | 执行像素格式转换和缩放 | sws_ctx: 转换上下文 srcSlice: 源数据指针 |
四、视频解码显示实战
实现一个ffmpeg读取视频文件,并使用opencv进行显示的例子。
4.1 实现流程图
4.2 完整实现代码
#include <opencv2/opencv.hpp>
extern "C" {
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}int main() {// 初始化FFmpegavformat_network_init();AVFormatContext* fmt_ctx = NULL;// 打开输入文件if(avformat_open_input(&fmt_ctx, "test.mp4", NULL, NULL) != 0){printf("无法打开文件\n");return -1;}// 获取流信息if(avformat_find_stream_info(fmt_ctx, NULL) < 0){printf("无法获取流信息\n");return -1;}// 查找视频流索引int video_stream = -1;for(int i=0; i<fmt_ctx->nb_streams; i++){if(fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO){video_stream = i;break;}}// 获取解码器参数AVCodecParameters* codec_par = fmt_ctx->streams[video_stream]->codecpar;const AVCodec* decoder = avcodec_find_decoder(codec_par->codec_id);// 初始化解码器上下文AVCodecContext* codec_ctx = avcodec_alloc_context3(decoder);avcodec_parameters_to_context(codec_ctx, codec_par);avcodec_open2(codec_ctx, decoder, NULL);// 准备转换上下文(YUV->RGB)SwsContext* sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt,codec_ctx->width, codec_ctx->height, AV_PIX_FMT_RGB24,SWS_BILINEAR, NULL, NULL, NULL);// 准备帧结构AVFrame* frame = av_frame_alloc();AVFrame* rgb_frame = av_frame_alloc();uint8_t* buffer = (uint8_t*)av_malloc(av_image_get_buffer_size(AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1));av_image_fill_arrays(rgb_frame->data, rgb_frame->linesize, buffer, AV_PIX_FMT_RGB24, codec_ctx->width, codec_ctx->height, 1);AVPacket pkt;while(av_read_frame(fmt_ctx, &pkt) >= 0){if(pkt.stream_index == video_stream){// 发送到解码器avcodec_send_packet(codec_ctx, &pkt);// 接收解码帧while(avcodec_receive_frame(codec_ctx, frame) == 0){// 格式转换sws_scale(sws_ctx, (const uint8_t* const*)frame->data, frame->linesize,0, codec_ctx->height,rgb_frame->data, rgb_frame->linesize);// OpenCV显示cv::Mat img(codec_ctx->height, codec_ctx->width, CV_8UC3, rgb_frame->data[0]);cv::imshow("Video", img);cv::waitKey(1);}}av_packet_unref(&pkt);}// 释放资源av_frame_free(&frame);av_frame_free(&rgb_frame);avcodec_free_context(&codec_ctx);avformat_close_input(&fmt_ctx);sws_freeContext(sws_ctx);return 0;
}
4.3 关键代码解析
- 图像转换配置:
sws_ctx = sws_getContext( // 创建转换器实例srcW, srcH, srcFormat, // 源图像参数dstW, dstH, dstFormat, // 目标图像参数flags, // 缩放算法选择...); // 其他可选参数
- OpenCV显示核心:
cv::Mat img(height, width, // 创建Mat对象CV_8UC3, // 数据类型:8位无符号3通道rgb_frame->data[0], // RGB数据首地址rgb_frame->linesize[0]); // 每行字节数(步长)
- 解码循环逻辑:
while(av_read_frame() >=0){ // 读取压缩包if(视频流){avcodec_send_packet(); // 送入解码队列while(avcodec_receive_frame() ==0){ // 获取解码帧// 处理帧数据}}av_packet_unref(); // 必须释放数据包
}
五、常见问题处理
- 颜色显示异常:检查像素格式转换参数(AV_PIX_FMT_RGB24)
- 无法打开文件:检查文件路径和FFmpeg的协议支持
- 内存泄漏:确保每个av_malloc都有对应的av_free
- 花屏现象:检查解码器是否成功初始化,数据包是否完整
相关文章:
FFmpeg视频处理入门级教程
一、FFmpeg常规处理流程 #mermaid-svg-W8X1llNEyuYptV3I {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-W8X1llNEyuYptV3I .error-icon{fill:#552222;}#mermaid-svg-W8X1llNEyuYptV3I .error-text{fill:#552222;str…...
PINN求解固体力学问题——论文加代码
PINN求解固体力学问题——论文加代码 1. 训练2. 可视化 论文:Physics-Informed Deep Learning and its Application in Computational Solid and Fluid Mechanics 1. 训练 # %load Plane_Stress_W-PINNs.py """ Forward Problem for Plane Stress …...
HC32F460_SCI驱动(一)
在开始介绍HC32F460的SCI驱动之前,先重点说明一下功能组与串口相关参数,以便于更好的描述SCI驱动。 1. 功能组 1.1 基本概念 HC32F460的引脚功能复用机制通过Func_Grp(功能组)实现,其灵活性显著高于传统单片机(如STM32系列)。每个引脚支持多种外设功能,具体功能通过选…...
程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图
大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 这一节我们来学习指针的相关知识,学习内存和地址,指针变量和地址,包…...
QT:QPen、QBrush、与图形抗锯齿的关联
QPen QPen 是 Qt 框架中用于定义绘图时使用的画笔属性的类。在使用 QPainter 进行 2D 绘图时,QPen 可以控制线条的外观,比如线条的颜色、宽度、样式(如实线、虚线等)、端点样式(如方形端点、圆形端点等)和…...
数据结构秘籍(一)线性数据结构
1.数组 数组(Array)是一种很常见的数据结构。它由相同类型的元素(element)组成,并且是使用一块连续的内存来存储。 我们直接可以利用元素的索引(index)计算出该元素对应的存储地址。 数组的特…...
【数据分享】2000-2024年全国逐年归一化植被指数(NDVI)栅格数据(年平均值)
NDVI,全名为Normalized Difference Vegetation Index,中文名称为归一化植被指数。这个指数可以用来定性和定量评价植被覆盖及其生长活力,我们也可以简单地将它理解为体现植被密度和健康状况的一个指标。 之前我们给大家分享了来源于MOD13A3数…...
解决前端计算的浮点精度问题
问题:比如1001*1.11等于110.11 但是如果用前端开发处理的话 ,因为涉及到浮点数运算(这是因为JavaScript(以及其他许多编程语言)使用IEEE 754标准来表示浮点数,导致某些十进制小数无法精确表示,…...
C语言基本知识------指针(4)
1. 回调函数是什么? 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数 时,被调⽤的函数就是回调函数。 void qsort(void base,//指针…...
004 Kafka异常处理
6.异常处理 文章目录 6.异常处理1.异常分类与处理原则2.生产者异常处理1. 同步发送捕获异常2. 异步发送回调处理 3.消费者异常处理1.全局异常处理器2.方法级处理3.重试yml配置 4.死信队列(DLQ)配置1. 启用死信队列2. 手动发送到DLQ 5.事务场景异常处理1.…...
C++模拟实现map和set
C模拟实现map和set 1、STL源代码分析2、实现出复用红黑树的框架3、实现红黑树的迭代器4、解决map和set中key不可修改问题5、解决insert返回值问题完整代码 模拟实现map和set实际上是对红黑树的封装,如对红黑树的实现有疑问,请移步:C手撕红黑树…...
使用elasticdump导出/导入 -- ES数据
导出指定索引数据到指定文件夹: ./elasticdump --inputhttp://用户:密码IP:9201/索引名字 --output导出路径/out.json --typedata 将导出的文件导入 ./elasticdump --input路径/out.json --outputhttp://账号:密码IP:9201/索引名称 --typedata --fileTypejson 【el…...
CSDN年度评选揭晓,永洪科技AI技术与智能应用双星闪耀
近日,永洪科技在CSDN(中国专业开发者社区)的年度评选中,凭借在人工智能技术创新与vividime在行业应用中的卓越表现,一举斩获“人工智能企业”及“智能应用”双料大奖。这一荣誉不仅彰显了永洪科技在AI领域的领先地位&a…...
Kubernetes 资源利用率翻倍?离在线混合部署深度解析
还在为 Kubernetes 集群资源利用率低而烦恼?还在为高昂的云成本而头疼?今天,我们就来聊聊 Kubernetes 中的一项黑科技——离在线混合部署,让大家的集群资源利用率翻倍,成本减半! 🤔 什么是离在线…...
【Java】Spring Boot全量YAML配置说明
目录 Spring Boot 配置文件基础核心配置日志配置Web 服务器配置数据源配置JPA 配置缓存配置国际化配置邮件服务配置自定义配置使用示例1. Spring Boot 配置文件基础 Spring Boot 的配置文件可以使用以下文件格式: application.propertiesapplication.ymlSpring Boot 默认加载…...
【STL】7.STL常用算法(1)
STL常用算法(1) 前言简介一.遍历算法1.for_each2.transform 二.查找算法1.find2.find_if3.adjacent_find4.binary_search5.count6.cout_if 三.排序算法1.sort2.random_shuffle3.merge4.reverse 总结 前言 stl系列主要讲述有关stl的文章,使用S…...
弱监督语义分割学习计划(1)-简单实现CAM但是效果不好
零: 项目说明 是这样的一个事情,经过与deepseek的一番讨论和交流,DeepSeek为我设计了一个30天高强度学习计划,重点聚焦弱监督/无监督语义分割在野外场景的应用,结合理论与实践,并最终导向可落地的开源项目。目前开始了…...
内存泄漏问题分享
在前端开发中,内存泄漏(Memory Leak)是指由于代码问题导致浏览器无法回收不再使用的内存,从而影响网页的性能,导致页面变慢,甚至崩溃。前端内存泄漏通常由以下几种原因引起,理解和修复这些问题对…...
用 DeepSeek 打样!KubeSphere LuBan 用 3 天/3 分钟“干掉”大模型部署焦虑
用 DeepSeek 打样!KubeSphere LuBan 用 3 天/3 分钟“干掉”大模型部署焦虑 大模型落地,如何告别“部署焦虑”? DeepSeek-R1 的惊艳表现无需赘述,但企业落地时的高门槛却让许多开发者望而却步——复杂的部署流程、资源调度难题、…...
Java在云计算平台中的应用研究
Java在云计算平台中的应用研究 随着云计算的广泛应用,越来越多的企业和开发者开始选择基于云计算的架构来构建和部署应用。Java作为一种成熟的编程语言,凭借其跨平台性、强大的生态系统以及优秀的并发处理能力,已成为云计算平台中常用的编程…...
【学写LibreCAD】0 仿写LibreCAD简介
一、LibreCAD 核心模块: 核心模块(Core) 功能:处理 CAD 的核心逻辑,如几何计算、图形对象管理、坐标系转换等。关键组件: 图形对象:如直线、圆、圆弧、多段线等。数学工具:向量、矩…...
【质量管理】怎么评估职能部门当前质量管理成熟度
评估目的 在做质量管理时,我们需要先了解各职能部门当前质量管理成熟度。从而识别改进机会,为各职能部门后续质量提升计划提供依据。 直白说:就是让那些不肯动的人动起来,同时往往总经理对各部门的质量管理成熟度的评分要更低&…...
音乐游戏Dance Dance Revolution(DDR)模拟器
文章目录 (一)Dance Dance Revolution(1.1)基本情况(1.2)机体 (二)模拟器(2.1)主程序(2.2)模拟器主题 (三)曲谱…...
【Pandas】pandas Series filter
Pandas2.2 Series Computations descriptive stats 方法描述Series.align(other[, join, axis, level, …])用于将两个 Series 对齐,使其具有相同的索引Series.case_when(caselist)用于根据条件列表对 Series 中的元素进行条件判断并返回相应的值Series.drop([lab…...
SpringBoot项目注入 traceId 来追踪整个请求的日志链路
SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排查问题的时候,可以迅速根据 traceId 查找到相关请求的日志,特别是在生产环境的时候,用户可能只提供一个错误截图,我们作为开发…...
UVM 软链接应用
软链接在环境中主要是为了代码复用,目前用到的场景有两种: 1)将UT 环境的代码 链接到ST环境上复用: 将ut 的transaction和sequence等在ST上复用 使用方法 在st对应目录下执行命令: ln -s 。…/xxxx/UT/xxx/xx_transact…...
SCIKIT-LEARN 决策树实现csv文档简单的推论预测
一.学习背景 原文来自scikit-learn的学习拓展,根据樱花分类示例衍生而来。源文开源地址:scikit-learn: machine learning in Python — scikit-learn 0.16.1 documentation,想学机器学习和数据挖掘的可以去瞧瞧! 二.读取csv文档 …...
VM虚拟机安装与配置Ubuntu Linux操作系统详细教程~
一、下载VM虚拟机 VMware16.0.zip百度网盘下载链接:https://pan.baidu.com/s/1-l-CcAVNINqhRLSiQ26R7w?pwd=tznn 提取码: tznn 二、软件介绍 VMware(虚拟机)是指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统,通过它可在一台电脑上同…...
使用 Ray的可观察性功能监控和调试 Ray 应用程序和集群
一、引言 在分布式系统中,监控和调试是确保系统稳定运行的关键环节。Ray 作为一款高性能的分布式计算框架,提供了丰富的可观察性(Observability)功能,帮助用户监控和调试 Ray 应用程序和集群。本文将详细介绍如何使用 Ray 的可观察性功能,包括监控工具、调试流程、日志管…...
jmeter 如何做移动端的测试 特别是兼容性测试
JMeter本身主要是一款用于性能测试和功能测试的工具,虽然它并非专门为移动端测试设计,但可以通过一些方式来对移动端应用进行测试,以下从测试准备、测试过程及注意事项等方面为你详细介绍: 一、测试准备 (一)环境搭建 JMeter安装与配置:确保JMeter已经正确安装在测试机…...
模板方法模式
模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的骨架,允许子类在不改变算法结构的情况下重写某些步骤的具体实现。 核心思想 抽象类定义模板方法(final 修饰,防止子类修改…...
64位精度HPC计算引擎的十年博弈:AMD如何以性价比颠覆NVIDIA霸权?
若期望一款中央处理器(CPU)具备图形处理器(GPU)级别的浮点运算性能,根据CPU发展路线图,大约需等待六年左右。这显然是一段漫长的等待期,这也解释了为何十五年前众多高性能计算(HPC&a…...
2P4M-ASEMI照明控制专用2P4M
编辑:ll 2P4M外观与基本结构 2P4M 可控硅通常封装在一个小巧的塑料外壳内,从外观上看,它有着几个标志性的引脚。一般为三脚结构,每个引脚都肩负着不同的使命。其内部结构精密复杂,核心是由多层半导体材料交替堆叠而成…...
【工程管理与安全工程方向 EI会议征稿 | EI Compendex、Scopus收录】2025年工程管理与安全工程国际学术会议 (EMSE 2025)
重要信息: 大会官网:www.ic-emse.com【论文投稿】 大会时间:2025年3月21-23日 大会地点:中国-南京 截稿时间:以官网信息为准 出版信息:<...
VMware work station 与Device/Credential Guard不兼容
1.出现如下错误 按 下Windows徽标键R 然后输入msinfo32.exe,会出现系统信息,在系统信息里找到基于虚拟化的安全性,查看是否打开 gpedit.msc 注册表修改...
STM32开发学习(三)----使用STM32CUBEMX创建项目
前言 开始正式接触代码,学习代码开发,先熟悉STM32CUBEMX软件,控制开发板的GPIO。(STM32F103C8T6)。 正式开始 1.打开软件 2.点击ACCESS TO MCU SELECTOR,进入软件选择,可能会弹出更新,等待更新完成即可。…...
smolagents学习笔记系列(七)Examples-Self-correcting Text-to-SQL
这篇文章锁定官网教程中 Examples 章节中的 Self-correcting Text-to-SQL 文章,主要介绍了如何使用 Agent 对数据库进行查找。 官网链接:https://huggingface.co/docs/smolagents/v1.9.2/en/examples/text_to_sql; 【注意事项】:…...
ffmpeg常用方法(一)
FFmpeg是一个非常强大的开源项目,提供了一套可以用来录制、转换数字音频、视频,并能将其转换成不同格式的工具和库。它是命令行工具,意味着它没有图形用户界面,但它能够被嵌入到其他应用程序中。它支持多种操作系统,包…...
c++:多态
1.多态 多态就是多种形态的意思。 分为编译时多态,也叫静态多态,通过传递不同参数的方式使同一个函数好像实现了不同的状态。eg:函数模板,函数重载 还有运行时多态,也叫动态多态。通过使用不同的对象调用“同一个函数”…...
Nuxt.js 3【详解】服务器 Server
Nuxt.js 是一个全栈框架,可以在一个项目中,同时完成前端和后端的开发。 服务器架构 Nuxt.js 的服务端由 Nitro 实现,Nitro 由基于 H3 实现。 Nitro 官网 https://nitro.build/guideH3 官网 https://h3.unjs.io/guide 接口路由 基于文件目录自…...
DeepSeek回答:AI时代Go语言学习路线
最近有小伙伴经常会问:**该如何学习入门Go语言?怎样提升Go语言Coding水平?**这篇文章我们就使用DeepSeek来梳理下Go语言在AI时代的学习路线。 向DeepSeek提问的问题原文: 你现在是一名资深的Go语言工程师,精通Go语言并…...
OpenGL 04--GLSL、数据类型、Uniform、着色器类
一、着色器 在 OpenGL 中,着色器(Shader)是运行在 GPU 上的程序,用于处理图形渲染管线中的不同阶段。 这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器…...
仅需三分钟,使用Vue3.x版本组件式风格实现一个消息提示组件!
一、前言 在日常的前端项目开发中,我们时常需要使用到“消息提示”(以下简称“消息”)这个组件来帮助我们更好的给予用户提示,例如常见的“登录成功”、“操作成功”、“服务器异常”等等提示。 尽管市面上已经有一些组件库提供了…...
天猫代运营公司推荐:品融电商
天猫代运营公司推荐:品融电商 在电商行业竞争日益激烈的今天,选择一家专业的天猫代运营公司成为众多品牌商家提升市场竞争力、实现销售增长的关键。在众多代运营公司中,品融电商凭借其专业的团队、丰富的经验和显著的成功案例,脱…...
2025.2.26#Java开发中的鉴权机制详解
1、Java开发中的鉴权机制详解 用户问的是在Java开发中什么是鉴权。首先,我需要明确鉴权的定义。鉴权,也就是认证授权,是确认用户身份和权限的过程。可能用户刚接触安全相关的内容,需要简单明了的解释。 接下来,我应该分…...
AF3 DataPipeline类解读
AlphaFold3 的DataPipeline类处理单链蛋白数据,主要负责从不同数据源(FASTA、PDB、mmCIF、ProteinNet .core 文件等)解析输入序列、MSA、模板匹配、序列嵌入(如 ESM-2)、并将其转换为 AlphaFold3 可用的特征格式。 源代码: class DataPipeline:"""Assem…...
Windows系统PyTorch环境配置
0、前言 深度学习为什么要配置GPU? GPU(图形处理单元)最初是为图形渲染而设计的,它们擅长处理大量并行计算任务。深度学习模型,特别是卷积神经网络(CNN)和循环神经网络(RNN…...
策略模式环境类的实现方式对比
文章目录 1、策略模式2、聚合策略类实现方式一3、聚合策略类实现方式二4、对比5、补充:ApplicationContextAware接口 1、策略模式 近期工作中,需要处理4.x和5.x两个版本的数据,所以自然想到的是策略模式,写一个抽象类,…...
深入理解JVM的运行时数据区
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
mapbox基础,加载background背景图层
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象…...