在CodeBlocks搭建SDL2工程虚拟TFT彩屏解码带压缩形式的Bitmap(BMP)图像显示
在CodeBlocks搭建SDL2工程虚拟TFT彩屏解码带压缩形式的Bitmap BMP图像显示
- 参考文章
- 文章说明
- 一、创建和退出SDL2
- 二、 Bitmap(BMP)图片解码图
- 三、Bitmap解码初始化
- 四、测试代码
- 五、主函数
- 六、测试结果
参考文章
- 解码带压缩形式的Bitmap(BMP)图像并使用Python可视化解码后实际图像
- 在CodeBlocks搭建SDL2工程构建TFT彩屏模拟器虚拟TFT彩屏幕显示
- 使用Python可视化有压缩格式的Bitmap(BMP)图像调色板数据
- 有压缩格式的Bitmap(BMP)图像显示调色板数据和图像数据
- Bitmap(BMP)图像信息分析主要说明带压缩的形式
- Bitmap(BMP)图像信息验证
文章说明
1. 在CodeBlocks上搭建SDL2工程,虚拟TFT彩屏模拟器2. 带压缩的Bitmap(BMP)图像解码后显示在TFT彩屏上3. Bitmap(BMP)原图垂直翻转后为真实样子
一、创建和退出SDL2
static AppGlobal_TypeDef AppSystem = {0};
AppGlobal_TypeDef * pAppSystem = &AppSystem;/* 初始化SDL */
static u8 ubInit_SDL2(void)
{/* 初始化SDL */if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0){SDL_Log("SDL Init Fail......%s\r\n", SDL_GetError());return 1;}/* 创建窗口 */AppSystem.MainWindow = SDL_CreateWindow("Virtual TFT SDL2", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_PHY_WIDTH, WINDOW_PHY_HEIGHT, SDL_WINDOW_SHOWN);if (AppSystem.MainWindow == NULL){SDL_Log("SDL Create Window Fail......%s\r\n", SDL_GetError());return 2;}/* 创建渲染器 */AppSystem.MainRender = SDL_CreateRenderer(AppSystem.MainWindow, -1, SDL_RENDERER_ACCELERATED);if (AppSystem.MainRender == NULL){SDL_Log("SDL Create Renderer Fail......%s", SDL_GetError());return 3;}/* 创建纹理 */AppSystem.MainTexture = SDL_CreateTexture(AppSystem.MainRender, SDL_PIXELFORMAT_ARGB8888 , SDL_TEXTUREACCESS_STATIC, TFT_LCD_PHY_XWIDTH, TFT_LCD_PHY_YHEIGHT);if (AppSystem.MainTexture == NULL){SDL_Log("SDL Create Texture Fail......%s", SDL_GetError());return 4;}/* 设置纹理模式 */SDL_SetTextureBlendMode(AppSystem.MainTexture, SDL_BLENDMODE_BLEND);memset(TFT_LCD_DIS_MEMORY, 0x99, TFT_LCD_PHY_XWIDTH * TFT_LCD_PHY_YHEIGHT * sizeof(u32));SDL_UpdateTexture(AppSystem.MainTexture, NULL, TFT_LCD_DIS_MEMORY, TFT_LCD_PHY_XWIDTH * sizeof(u32));SDL_RenderClear(AppSystem.MainRender);SDL_RenderCopy(AppSystem.MainRender, AppSystem.MainTexture, NULL, NULL);SDL_RenderPresent(AppSystem.MainRender);return 0;
}/* 退出SDL */
static void vQuit_SDL2(void)
{SDL_Log("Complier Date: %s %s %d\r\n", __DATE__, __TIME__, ulSuperTimer_GetTick());/* 销毁纹理 */if (AppSystem.MainTexture != NULL) SDL_DestroyTexture(AppSystem.MainTexture);/* 销毁渲染器 */if (AppSystem.MainRender != NULL) SDL_DestroyRenderer(AppSystem.MainRender);/* 销毁窗口 */if (AppSystem.MainWindow != NULL) SDL_DestroyWindow(AppSystem.MainWindow);/* 退出SDL */SDL_Quit();
}
二、 Bitmap(BMP)图片解码图
/* 获取调色板数据 */
void vGet_Color_Palette(const u8 * pSrcDat, u32 * pColorDat, u16 count)
{u16 i = 0;u32 * pARGB = (u32 *)(pSrcDat + sizeof(BitmapInfo_TypeDef));for (i = 0; i < count; ++i){pColorDat[i] = *pARGB++;}
}/* 解码数据写入文件中 */
static void vBitmap_Write_File(void)
{u32 i = 0;/* 将解码后数据写入文件中 */FILE * wFileHandler= fopen("xDemo.txt", "a+"); if (wFileHandler == NULL) {printf("Open File Error......\n");return;}fprintf(wFileHandler, "Width:%u Height:%u\n", AppBmpDecode->pBmpInfo->InfoHeader.ImgWidth, AppBmpDecode->pBmpInfo->InfoHeader.ImgHeight);for (i = 0; i < AppBmpDecode->Index; ++i){if (i && ((i % 10) == 0)) fprintf(wFileHandler, "\n");fprintf(wFileHandler, "'#%08X',", AppBmpDecode->pDisMemory[i]);}fprintf(wFileHandler, "\r\n\r\n");if (wFileHandler == NULL) {fclose(wFileHandler);}
}/* Bitmap图片解码 */
void vDecode_Bitmap(const u8 * pSrcDat)
{const u8 * pDat = NULL;Type8Bits_TypeDef bitDat = {0};BitmapInfo_TypeDef bitmapInfo = {0};u32 widthCount = 0, heightCount = 0;u32 color = 0, temp = 0;u16 i = 0, num = 0, count = 0;u16 line = 0, colum = 0;/* 获取Bitmap信息 */memcpy((void *)(&bitmapInfo), (const void *)pSrcDat, sizeof(BitmapInfo_TypeDef));/* 获取调色板数据 */vGet_Color_Palette(pSrcDat, AppBmpDecode->pColorPalette, bitmapInfo.InfoHeader.ColorPalette);/* 显示调色板数据 */// vShow_Color_Palette(AppBmpDecode->pColorPalette, bitmapInfo.InfoHeader.ColorPalette);/* 颜色数据 */pDat = pSrcDat + bitmapInfo.FileHeader.ImgDataOffset;/* 解码索引 */AppBmpDecode->Index = 0;while(1){if (*pDat == 0){pDat++;switch (*pDat){case 0x00: //00 00 行结束{pDat++;/* 宽度计数不够 */if (bitmapInfo.InfoHeader.ImgWidth >= widthCount){/* 剩余的宽度部分 */temp = bitmapInfo.InfoHeader.ImgWidth - widthCount;if (!bitDat.Bits.Bit0){bitDat.Bits.Bit0 = 1;// printf("Tips2......%u\r\n", AppBmpDecode->Index);}}else{/* 宽度计数超过图像宽度 剩余的宽度部分计算 */temp = bitmapInfo.InfoHeader.ImgWidth - (widthCount % bitmapInfo.InfoHeader.ImgWidth);/* 跨宽度的高度数量 */heightCount += (widthCount / bitmapInfo.InfoHeader.ImgWidth);if (!bitDat.Bits.Bit1){bitDat.Bits.Bit1 = 1;// printf("Tips3......%u\r\n", AppBmpDecode->Index);}}/* 增加高度计数 */heightCount++;/* 高度计数已大于图像高度,提前结束 */if (heightCount >= bitmapInfo.InfoHeader.ImgHeight){bitDat.Bits.Bit7 = 1;// printf("Tips5......%u\r\n", AppBmpDecode->Index);}/* 清零宽度计数 */widthCount = 0;/* 剩余的宽度部分需填充颜色 */AppBmpDecode->Index += temp;}break;case 0x01: //00 01 图像结束{/* 计算剩余需要填充的像素点大小 */temp = (bitmapInfo.InfoHeader.ImgHeight - heightCount - 1) * bitmapInfo.InfoHeader.ImgWidth + (bitmapInfo.InfoHeader.ImgWidth - widthCount);// temp = (bitmapInfo.InfoHeader.ImgHeight * bitmapInfo.InfoHeader.ImgWidth) - AppBmpDecode->Index;// printf("Tips4......%u ", AppBmpDecode->Index);AppBmpDecode->Index += temp;bitDat.Bits.Bit7 = 1;// printf("%u %u %u\r\n", AppBmpDecode->Index, heightCount, temp);}break;case 0x02: //00 02 跳转水平和垂直偏移量{colum = *(pDat + 1); //xline = *(pDat + 2); //ypDat += 3;/* 宽度计数 */widthCount += colum;/* 高度计数 */heightCount += line;// if (!bitDat.Bits.Bit2) printf("Tips1......index0:%u ", AppBmpDecode->Index);/* 跳转到指定位置 */AppBmpDecode->Index += bitmapInfo.InfoHeader.ImgWidth * line + colum;// if (!bitDat.Bits.Bit2)// {// bitDat.Bits.Bit2 = 1;// printf("index0:%u %u %u %u %u\r\n", AppBmpDecode->Index, colum, line, bitmapInfo.InfoHeader.ImgWidth, bitmapInfo.InfoHeader.ImgHeight);// }}break;default: //00 03~FF 单像素数量+调色板索引{count = num = *pDat;widthCount += num;pDat++;for (i = 0; i < num; ++i){/* 单像素颜色 */AppBmpDecode->pDisMemory[AppBmpDecode->Index++] = AppBmpDecode->pColorPalette[*pDat++];}/* 对齐 */if (count & 0x01){pDat++;}}break;}}else{count = *pDat;color = AppBmpDecode->pColorPalette[*(pDat + 1)];widthCount += count;pDat += 2;for (i = 0; i < count; ++i){AppBmpDecode->pDisMemory[AppBmpDecode->Index++] = color;}}/* 结束 */if (bitDat.Bits.Bit7) {break;}}/* 解码数据写入文件中 */// vBitmap_Write_File();
}
三、Bitmap解码初始化
/* 初始化Bitmap解码 */
void vInit_Bitmap_Decode(void)
{BitmapDecode.pDisMemory = BitmapDecodeDisplayMemory;BitmapDecode.pColorPalette = BitmapDecodeColorPalette;BitmapDecode.pImageData = BitmapDecodeImageData;BitmapDecode.pBmpInfo = &BitmapDecodeBitmapInfo;BitmapDecode.Index = 0;AppBmpDecode = (BitmapDecode_TypeDef *)(&BitmapDecode);
}void vClear_BmpDecode_Memory(void)
{memset((void *)BitmapDecode.pDisMemory, 0, (BMP_DECODE_DISPLAY_MEMORY_SIZE << 2));memset((void *)BitmapDecode.pColorPalette, 0, (BMP_DECODE_COLOR_PALETTE_SIZE << 2));memset((void *)BitmapDecode.pImageData, 0, BMP_DECODE_IMAGE_DATA_SIZE);memset((void *)BitmapDecode.pBmpInfo, 0, sizeof(BitmapInfo_TypeDef));BitmapDecode.Index = 0;
}
四、测试代码
void vTFT_LCD_FillRect_MultColor1(u32 x, u32 y, u32 width, u32 height, ColorType * pColor)
{u32 count = 0;u32 x0 = 0, y0 = 0, ex = 0, ey = 0;for (y0 = y; y0 <= (y + height - 1); y0++){for (x0 = x; x0 <= (x + width - 1); x0++){AppDevTFT.pDisMem[AppDevTFT.xWidth * y0 + x0] = 0xFF000000 | DEV_RGB(*pColor++);count++;}}printf("width:%-5u height:%-5u count:%-5u X:%-5u Y:%-5u\r\n", width, height, count, x0, y0);
}const u8 * xDat[12] =
{(const u8 *)"xDemoUI\\b128_t_vol3.bmp",(const u8 *)"xDemoUI\\b064_p_delay.bmp",(const u8 *)"xDemoUI\\b089_td_meas.bmp",(const u8 *)"xDemoUI\\b112_t_p2p2.bmp",(const u8 *)"xDemoUI\\b110_t_level.bmp",(const u8 *)"xDemoUI\\b106_t_area1.bmp",(const u8 *)"xDemoUI\\b101_t_2pyth2.bmp",(const u8 *)"xDemoUI\\b380_td_contmeas.bmp",(const u8 *)"xDemoUI\\b109_t_cylin2.bmp",(const u8 *)"xDemoUI\\b127_t_vol2.bmp",(const u8 *)"xDemoUI\\b042_m_stake2.bmp",(const u8 *)"xDemoUI\\b120_t_trapz2.bmp",
};void vDemoTest(void)
{static u8 count = 0;const u8 * pSrcDir = NULL;FILE * pImgFileHandler = NULL;pSrcDir = xDat[count];if ((++count) >= 12) count = 0;/* 打开文件 */pImgFileHandler = fopen(pSrcDir, "rb");if (pImgFileHandler == NULL) {printf("Open File Error......\r\n");while (1); }vClear_BmpDecode_Memory();/* 读取Bitmap信息 */if (!fread(AppBmpDecode->pBmpInfo, sizeof(BitmapInfo_TypeDef), 1, pImgFileHandler)) {printf("Read Bitmap Info Error......\r\n");while (1);}/* 设置文件指针偏移 */if (fseek(pImgFileHandler, 0, SEEK_SET)){printf("Set Offset Error.....1\r\n");while (1);}/* 读取整个文件内容 */if (!fread(AppBmpDecode->pImageData, AppBmpDecode->pBmpInfo->FileHeader.FileSize, 1, pImgFileHandler)) {printf("Read File Data Error......2\r\n");while (1);}vTFT_LCD_FillRect_SingColor(10, 50, AppDevTFT.xWidth - 10, AppDevTFT.yHeight - 10, 0);vDecode_Bitmap((const u8 *)AppBmpDecode->pImageData);vTFT_LCD_FillRect_MultColor1(30, 60, AppBmpDecode->pBmpInfo->InfoHeader.ImgWidth, AppBmpDecode->pBmpInfo->InfoHeader.ImgHeight, AppBmpDecode->pDisMemory);ubSuperTimer_Start(vDemoTest, 1500);
}
五、主函数
int main( int argc, char * argv[] )
{if (ubInit_SDL2()){SDL_Log("Init SDL Fail......%s\r\n", SDL_GetError());vQuit_SDL2();return -1;}vTFT_Init();xSuperTimer_Init();vInit_Bitmap_Decode();AppSystem.ExitWindow = EXIT_WINDOW_TYPE_RUN;ubSuperTimer_Start(xDemo, 3000);while (AppSystem.ExitWindow){vRefresh_KeyEvent_Handler();vSystem_BasicTick();vSuperTimer_RunHandler();}vQuit_SDL2();return 0;
}
六、测试结果




相关文章:
在CodeBlocks搭建SDL2工程虚拟TFT彩屏解码带压缩形式的Bitmap(BMP)图像显示
在CodeBlocks搭建SDL2工程虚拟TFT彩屏解码带压缩形式的Bitmap BMP图像显示 参考文章文章说明一、创建和退出SDL2二、 Bitmap(BMP)图片解码图三、Bitmap解码初始化四、测试代码五、主函数六、测试结果 参考文章 解码带压缩形式的Bitmap(BMP)图像并使用Python可视化解码后实际图…...
解决QPixmap报“QPixmap::grabWindow(): Unable to copy pixels from framebuffer“问题
今天在使用QPixmap::grabWindow()截图时,弹出“QPixmap::grabWindow(): Unable to copy pixels from framebuffer”错误。 问题原因:QPixmap::grabWindow()这个函数适用于Qt5版本截屏,但该函数在Qt4上表现不稳定,经常出现“Unable…...
mapbox进阶,添加绘图扩展插件,绘制任意方向矩形
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️MapboxDraw 绘图控件二、🍀添加绘图扩…...
初阶c语言(循环语句习题,完结)
前言: c语言为b站鹏哥,嗯对应视频37集 昨天做的c语言,今天在来做一遍,发现做错了 今天改了平均值的计算, 就是说最大值加上最小值,如果说这个数值非常大的话,两个值加上会超过int类型的最大…...
提升编程效率,体验智能编程助手—豆包MarsCode一键Apply功能测评
提升编程效率,体验智能编程助手—豆包MarsCode一键Apply功能测评 🌟 嗨,我是LucianaiB! 🌍 总有人间一两风,填我十万八千梦。 🚀 路漫漫其修远兮,吾将上下而求索。 目录 引言豆包…...
【deepseek-r1本地部署】
首先需要安装ollama,之前已经安装过了,这里不展示细节 在cmd中输入官网安装命令:ollama run deepseek-r1:32b,开始下载 出现success后,下载完成 接下来就可以使用了,不过是用cmd来运行使用 可以安装UI可视化界面&a…...
多用户商城系统的客服管理体系建设
多用户商城系统的运营,客服管理体系建设至关重要。优质的客服服务不仅能提升用户购物体验,还能增强用户对商城的信任与忠诚度,进而促进商城业务的持续增长。以下从四个关键方面探讨如何建设完善的客服管理体系,信息化客服系统在其…...
K8S容器启动提示:0/2 nodes are available: 2 Insufficient cpu.
问题:K8S的容器启动报错0/2 nodes are available: 2 Insufficient cpu. 原因:Pod的资源请求(requests)设置不当:在Kubernetes中,调度器根据Pod的requests字段来决定哪个节点可以运行该Pod。如果一个Pod声明…...
C++设计模式 - 模板模式
一:概述 模板方法(Template Method)是一种行为型设计模式。它定义了一个算法的基本框架,并且可能是《设计模式:可复用面向对象软件的基础》一书中最常用的设计模式之一。 模板方法的核心思想很容易理解。我们需要定义一…...
CZML 格式详解,javascript加载导出CZML文件示例
示例地址:https://dajianshi.blog.csdn.net/article/details/145573994 CZML 格式详解 1. 什么是 CZML? CZML(Cesium Zipped Markup Language)是一种基于 JSON 的文件格式,用于描述地理空间数据和时间动态场景。它专…...
安装并配置 MySQL
MySQL 是世界上最流行的开源关系型数据库管理系统之一,因其高性能、可靠性和易用性而被广泛应用于各种规模的企业级应用中。本文将详细介绍如何在不同的操作系统上安装和配置 MySQL,帮助你快速搭建起一个功能完善的数据库环境。 选择适合你的安装方式 …...
OpenAI推出全新AI助手“Operator”:让人工智能帮你做事的新时代!
引言 随着人工智能技术的不断发展,OpenAI 再次推出令人兴奋的功能——Operator,一个全新的 AI 助手平台。这不仅仅是一个普通的助手,它代表了人工智能技术的又一次飞跃,将改变我们工作和生活的方式。 什么是“Operator”ÿ…...
TensorBoard和Wandb的介绍
TensorBoard 介绍 TensorBoard 是 TensorFlow 提供的一个可视化工具,主要用于帮助开发者监控和分析机器学习模型的训练过程。它的主要功能包括: 模型结构可视化:直观展示神经网络的结构。 训练指标可视化:实时监控训练过程中的损…...
重看Spring聚焦BeanFactory分析
目录 一、理解BeanFactory (一)功能性理解 (二)BeanFactory和它的子接口 (三)BeanFactory的实现类 二、BeanFactory根接口 (一)源码展示和理解 (二)基…...
Python基础(上)
1. 基础语法 1.1 环境安装 Python版本: 推荐使用Python 3.6.6及以上开发工具: PyCharm 1.2 基本语法 输出: print("Hello World") 注释: 单行注释: # 注释内容(快捷键 Ctrl/) 多行注释: 使用三引号 注释内容 注意:不推…...
将Docker容器打包成镜像提交
前言 Docker 是一个开源软件,也是一个开放平台,用于开发应用、交付(shipping)应用、运行应用。 Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容…...
一文通俗理解为什么需要泛型以及泛型的使用
为什么需要泛型? public static void main(String[] args) {ArrayList list new ArrayList();// 由于集合没有做任何限定,任何类型都可以给其中存放list.add("abc");list.add("def");list.add(5);Iterator it list.iterator();wh…...
人工智能时代下ai智能语音机器人如何以假乱真?
智能语音机器人若要达到以假乱真的效果,需要在以下几个关键方面不断提升: 一、语音合成技术 音色模拟 多维度采样 对大量真人语音样本进行多维度采样,包括不同年龄、性别、地域的人的语音。例如,采集不同年龄段男性从低沉到清亮…...
Sam Altman 揭秘 OpenAI 未来蓝图:GPT-4.5、GPT-5 与模型规范重大更新
OpenAI CEO Sam Altman 近日在 X 平台(原 Twitter)上分享了关于 GPT-4.5 (代号 “Orion”) 和 GPT-5 的最新进展,同时公布了 OpenAI 模型规范(Model Spec)的重大更新,强调知识自由与模型行为准则。 核心亮…...
老牌系统工具箱,现在还能打!
今天给大家分享一款超实用的电脑软硬件检测工具,虽然它是一款比较“资深”的软件,但依然非常好用,完全能满足我们的日常需求。 电脑软硬件维护检测工具 功能强大易用 这款软件非常贴心,完全不需要安装,直接打开就能用…...
在vivado中对数据进行延时,时序对齐问题上的理清
在verilog的ISP处理流程中,在完成第一个模块的过程中,我经常感到困惑,到底是延时了多少个时钟?今日对这几个进行分类理解。 目录 1.输入信号激励源描述 1.1将数据延时[9]个clk 1.2将vtdc与hzdc延时[9]个clk(等价于单bit的数据…...
Django REST Framework:如何获取序列化后的ID
Django REST Framework:如何获取序列化后的ID 😄 嗨,小伙伴们!今天我们来聊一聊Django REST Framework(简称DRF)中一个非常常见的操作:如何获取序列化后的ID。对于那些刚入门的朋友们ÿ…...
QT笔记——QPlainTextEdit
文章目录 1、概要2、文本设计2.1、设置文本2.1、字体样式(大小、下划线、加粗、斜体) 1、概要 QPlainTextEdit 是 Qt 框架中用于处理纯文本编辑的控件,具有轻量级和高效的特点,以下是它常见的应用场景: 文本编辑器&am…...
链表 —— 常用技巧与操作总结详解
引言 链表作为一种动态数据结构,以其灵活的内存管理和高效的插入删除操作,在算法与工程实践中占据重要地位。然而,链表的指针操作复杂,容易引发内存泄漏和野指针问题。本文博主将从基础操作到高阶技巧,系统化解析链表的…...
Linux下学【MySQL】常用函数助你成为数据库大师~(配sql+实操图+案例巩固 通俗易懂版~)
绪论 每日激励:“唯有努力,才能进步” 绪论: 本章是MySQL中常见的函数,利用好函数能很大的帮助我们提高MySQL使用效率,也能很好处理一些情况,如字符串的拼接,字符串的获取,进制…...
【C++BFS 离散化】1036. 逃离大迷宫|2164
本文涉及知识点 CBFS算法 LeetCode1036. 逃离大迷宫 在一个 106 x 106 的网格中,每个网格上方格的坐标为 (x, y) 。 现在从源方格 source [sx, sy] 开始出发,意图赶往目标方格 target [tx, ty] 。数组 blocked 是封锁的方格列表,其中每个…...
[c语言日寄]在不完全递增序中查找特定要素
【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋:这是一个专注于C语言刷题的专栏,精选题目,搭配详细题解、拓展算法。从基础语法到复杂算法,题目涉及的知识点全面覆盖,助力你系统提升。无论你是初学者,还是…...
HtmlRAG:RAG系统中,HTML比纯文本效果更好
HtmlRAG 方法通过使用 HTML 而不是纯文本来增强 RAG 系统中的知识表示能力。通过 HTML 清洗和两步块树修剪方法,在保持关键信息的同时缩短了 HTML 文档的长度。这种方法优于现有基于纯文本的RAG的性能。 方法 其实主要看下围绕html提纯思路,将提纯后的…...
LeetCode题解:2690. 无穷方法对象,Proxy
Problem: 2690. 无穷方法对象 思路 这个问题的核心在于创建一个对象,该对象能够响应对其任何方法的调用,并返回调用的方法名称。为了实现这一点,我们可以利用 JavaScript 中的 Proxy 对象。Proxy 对象允许我们自定义对象的基本操作ÿ…...
在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档教程
既然我们已经在本地部署了DeepSeek,肯定希望能够利用本地的模型对自己软件开发、办公文档进行优化使用,接下来就先在WPS中通过JavaScript宏(JSA)调用本地DeepSeek API优化文档的教程奉上。 前提: (1)已经部署好了DeepSeek,可以看我的文章:个人windows电脑上安装DeepSe…...
