GDI实时抗锯齿实战:从像素填充到AlphaBlend边缘混合

简介:这份资源面向使用 Windows GDI 进行图形绘制的 VC++ 开发者,针对 LineTo、Ellipse 等函数在曲线与斜线处产生的明显锯齿问题,提供了一套可实时运行的抗锯齿源代码方案。其核心思路是通过边缘检测识别边界像素,再对邻近像素颜色做加权混合,使边缘过渡更平滑,并可能结合多级采样、SIMD 并行处理与预计算缓存来兼顾画质与效率,还涉及按分辨率、色深动态调整策略的机制。压缩包为 rar 格式,共 69 个文件,约 312KB,包含源码与演示程序压缩包、htm 说明页面,以及 gif、png、jpg 等效果对比图与 js、css 等网页辅助文件,便于直接编译验证与效果对照。目前已有 847 人学习下载,适合希望提升 GDI 绘图质量、研究抗锯齿算法实现与性能优化的开发者参考借鉴。

1. GDI 实时消除图像锯齿:为什么你画的圆总是带毛边

用 GDI 画过一个圆或者一条斜线的人,大概率都见过那种阶梯状的毛边。明明代码里Ellipse的参数没问题,屏幕上的弧线却像被狗啃过。这不是你写错了,而是 GDI 默认走的是最朴素的像素填充路径——它只管把像素点亮,不管边缘过渡。实时消除图像锯齿,核心要解决的就是在每帧绘制时对边缘像素做透明度混合,让硬边变成渐变边。这件事在 GDI 里能做,但需要绕开默认的绘制管线,自己接管边缘采样和混合。适合谁看?做工业上位机、老式 Win32 工具、监控画面叠加、自定义控件绘制的开发者。如果你正在用 GDI 画仪表盘、波形图、地图标记,并且被锯齿问题卡住,这篇就是给你写的。下面从原理到代码,把实时抗锯齿这条路走通。

2. GDI 抗锯齿的底层逻辑:为什么默认管线做不到

2.1 GDI 的像素填充模型与锯齿来源

GDI 的绘制模型非常直接:给定一个几何描述,它计算出哪些像素落在图形内部,然后把这些像素设成目标颜色。对于一条斜线,落在理想直线上的像素被点亮,相邻像素保持背景色。人眼看到的就是阶梯。锯齿的本质是空间采样不足——连续几何被离散化成像素网格时,边缘没有过渡信息。

GDI 本身不提供抗锯齿开关。SetGraphicsMode切到高级模式也只影响坐标变换,不改变边缘混合。SmoothingMode是 GDI+ 的东西,GDI 没有对应 API。所以想在 GDI 里做实时抗锯齿,必须自己控制边缘像素的 alpha 值。

常见做法是:先用 GDI 把图形画到一张 32 位 DIB 上,然后对边缘区域做一次卷积或者距离场计算,把边缘像素的 alpha 按覆盖率重新赋值,最后用AlphaBlend贴回目标 DC。这个过程每帧都要跑,所以叫实时。

2.2 实时抗锯齿的三种可行路径对比

在 GDI 环境下,能落地的实时抗锯齿方案主要有三类:

方案原理单帧耗时(1080p 局部区域)适用场景
超采样降采样以 2x 或 4x 分辨率绘制后缩小8~20ms静态或低帧率画面
边缘覆盖率计算对边缘像素算几何覆盖率2~6ms动态图形、仪表盘
预乘 alpha 混合绘制时直接写 alpha 通道1~3ms自定义渲染管线

超采样最省事,但显存和带宽翻倍,实时场景下容易掉帧。边缘覆盖率计算是折中方案,只处理边缘附近的像素,适合 GDI 这种 CPU 绘制环境。预乘 alpha 混合最快,但要求你从绘制阶段就自己控制像素写入,不能直接用LineTo、Ellipse这些 API。

我一般会选边缘覆盖率计算,因为改动量小,可以在现有 GDI 绘制代码后面挂一个后处理步骤。下面按这个路径展开。

2.3 用 32 位 DIB 接管绘制目标

GDI 的CreateCompatibleDC默认是设备相关位图,拿不到稳定的像素格式。要做 alpha 混合,必须用CreateDIBSection建一张 32 位顶朝下的 DIB,选进内存 DC,所有绘制先落在这张 DIB 上。

// 创建 32 位 DIB,用于后续 alpha 混合 BITMAPINFO bmi = {}; bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = -height; // 负数表示顶朝下,方便按行遍历 bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = 32; bmi.bmiHeader.biCompression = BI_RGB; void* pBits = nullptr; HBITMAP hDib = CreateDIBSection(hdcScreen, &bmi, DIB_RGB_COLORS, &pBits, nullptr, 0); HDC hMemDC = CreateCompatibleDC(hdcScreen); HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hDib);

逻辑说明:biHeight设为负数让 DIB 顶朝下,这样pBits的第一行就是屏幕最上面一行,后续按行处理边缘时不用翻转。pBits指向像素数据,每个像素 4 字节,格式是 BGRA(小端下是蓝、绿、红、alpha)。参数说明:width和height是目标区域尺寸,建议按窗口客户区大小建,不要每帧重建,缓存起来复用。

选进内存 DC 后,所有 GDI 绘制调用都作用在这张 DIB 上。画完后pBits里就是完整的像素数据,可以逐像素做边缘检测和 alpha 修正。

3. 边缘覆盖率计算:从像素数据到抗锯齿输出

3.1 边缘检测:找出需要处理的像素

不是所有像素都需要抗锯齿。只处理图形边缘附近的像素,能大幅降低计算量。边缘检测的思路很简单:遍历像素,如果某个像素的颜色和它上下左右四个邻居差异超过阈值,就标记为边缘候选。

// 边缘候选标记,edgeMap 大小与 DIB 像素数一致 std::vector<uint8_t> edgeMap(width * height, 0); const int kEdgeThreshold = 30; // 颜色差异阈值,根据背景对比度调整 for (int y = 1; y < height - 1; ++y) { uint32_t* row = (uint32_t*)((uint8_t*)pBits + y * width * 4); uint32_t* rowPrev = (uint32_t*)((uint8_t*)pBits + (y - 1) * width * 4); uint32_t* rowNext = (uint32_t*)((uint8_t*)pBits + (y + 1) * width * 4); for (int x = 1; x < width - 1; ++x) { uint32_t c = row[x]; int diff = 0; diff += abs((int)(c & 0xFF) - (int)(row[x - 1] & 0xFF)); diff += abs((int)((c >> 8) & 0xFF) - (int)((row[x - 1] >> 8) & 0xFF)); diff += abs((int)((c >> 16) & 0xFF) - (int)((row[x - 1] >> 16) & 0xFF)); // 再比较上方和下方像素,取最大差异 // ... 省略重复比较逻辑 if (diff > kEdgeThreshold) { edgeMap[y * width + x] = 1; } } }

逻辑说明:对每个像素,分别和左、右、上、下邻居比较 RGB 三通道的绝对差之和,超过阈值就标记。阈值kEdgeThreshold是关键参数,背景和前景对比度低时调小,噪点多时调大。一般 20 到 50 之间。这段代码只做标记,不修改像素,为下一步覆盖率计算做准备。

3.2 覆盖率估算与 alpha 赋值

标记出边缘像素后,需要估算每个边缘像素被图形覆盖的比例。最实用的方法是 3x3 子采样:把当前像素当成一个 3x3 的网格,统计有多少个子点落在图形内部。但 GDI 绘制后已经丢失了几何信息,所以改用颜色距离来近似。

具体做法:对边缘像素,取它周围 8 个邻居中颜色最接近背景的作为背景参考,颜色最接近前景的作为前景参考。然后计算当前像素颜色在背景到前景连线上的投影比例,这个比例就是覆盖率。

// 对边缘像素估算覆盖率并写入 alpha for (int y = 1; y < height - 1; ++y) { uint32_t* row = (uint32_t*)((uint8_t*)pBits + y * width * 4); for (int x = 1; x < width - 1; ++x) { if (!edgeMap[y * width + x]) continue; uint32_t c = row[x]; // 简化处理:用亮度差估算覆盖率 int lum = ((c >> 16) & 0xFF) * 30 + ((c >> 8) & 0xFF) * 59 + (c & 0xFF) * 11; lum /= 100; // 假设背景亮度为 bgLum,前景亮度为 fgLum // coverage = (lum - bgLum) / (fgLum - bgLum) // 这里用固定背景和前景亮度做示例 int bgLum = 240; // 浅色背景 int fgLum = 40; // 深色前景 float coverage = (float)(lum - bgLum) / (fgLum - bgLum); if (coverage < 0.0f) coverage = 0.0f; if (coverage > 1.0f) coverage = 1.0f; // 将覆盖率写入 alpha 通道,RGB 保持前景色 uint8_t alpha = (uint8_t)(coverage * 255); row[x] = (alpha << 24) | (c & 0x00FFFFFF); } }

逻辑说明:亮度公式用的是人眼感知加权,比简单平均更接近视觉结果。bgLum和fgLum需要根据实际场景调整,如果背景是渐变或者前景有多种颜色,这个简化会失效,需要改成逐像素找最近前景和背景色。参数说明:coverage被钳制在 0 到 1 之间,避免浮点误差导致 alpha 溢出。写入时只改 alpha 字节,RGB 保留原值,这样后续AlphaBlend会按 alpha 混合。

3.3 用 AlphaBlend 输出到目标 DC

处理完 DIB 后,用AlphaBlend把带 alpha 的 DIB 贴到窗口 DC。AlphaBlend是 GDI 自带的函数,支持逐像素 alpha 混合,速度比手动循环快。

BLENDFUNCTION bf = {}; bf.BlendOp = AC_SRC_OVER; bf.SourceConstantAlpha = 255; // 使用每像素 alpha bf.AlphaFormat = AC_SRC_ALPHA; AlphaBlend(hdcScreen, 0, 0, width, height, hMemDC, 0, 0, width, height, bf);

逻辑说明:AC_SRC_ALPHA告诉AlphaBlend使用源 DIB 的 alpha 通道。SourceConstantAlpha设为 255 表示不额外叠加全局透明度。参数说明:如果目标 DC 已经有内容,AlphaBlend会把源按 alpha 混合上去,实现边缘渐变。注意AlphaBlend要求源 DIB 是预乘 alpha 还是直通 alpha 取决于系统,Windows 2000 以后直通 alpha 也能工作,但预乘更稳定。如果发现边缘发黑,把 RGB 值乘以 alpha 再写入。

4. 避坑与排查:实时抗锯齿翻车现场

4.1 边缘出现黑边或白边

现象:抗锯齿后图形边缘有一圈黑边或者白边,颜色不对。原因:alpha 混合时 RGB 没有预乘,或者背景色被错误地混入了边缘像素。解决:在写入 alpha 之前,把 RGB 值乘以覆盖率再写回,也就是预乘 alpha。如果背景不是纯色,需要先把背景画到 DIB 上,再画前景,最后统一算覆盖率。

4.2 帧率骤降,CPU 占用飙升

现象:开启抗锯齿后帧率从 60 掉到 20 以下。原因:每帧遍历全屏像素做边缘检测,计算量太大。解决:只处理上一帧和当前帧有变化的区域,用InvalidateRect的脏矩形做局部更新。另外边缘检测可以隔行采样,或者用查表法替代浮点运算。我一般会把边缘检测的阈值判断改成整数比较,避免浮点。

4.3 AlphaBlend 返回失败或画面全黑

现象:调用AlphaBlend后窗口全黑,或者函数返回 FALSE。原因:内存 DC 的位图没有选对,或者 DIB 的 alpha 通道全是 0。解决:检查SelectObject是否成功,确认pBits里的 alpha 字节被正确写入。另外AlphaBlend需要msimg32.lib,链接时别漏。如果 DIB 是顶朝下的,AlphaBlend的坐标参数不用翻转,但有些驱动对负高度 DIB 支持不好,可以改成底朝下再翻转行序。

4.4 文字和细线被过度模糊

现象:抗锯齿后文字发虚,1 像素宽的线几乎看不见。原因:覆盖率估算把细线的 alpha 压得太低,或者边缘检测把文字笔画当成了噪点。解决:对文字区域跳过抗锯齿,或者单独用 GDI 的ExtTextOut配合SetBkMode(TRANSPARENT)绘制。细线的话,把覆盖率的下限抬高,比如低于 0.3 的直接设为 0.3,保证可见度。

4.5 多显示器 DPI 缩放后错位

现象:在 125% 或 150% 缩放的显示器上,抗锯齿区域和图形对不上。原因:DIB 尺寸按物理像素算,但 GDI 绘制坐标是按逻辑坐标走的。解决:用GetDpiForWindow拿到缩放比例,DIB 尺寸乘以缩放比,绘制时用SetMapMode或者手动缩放坐标。AlphaBlend的目标尺寸也要按物理像素传。

5. 进阶技巧:把抗锯齿做成可复用的 GDI 封装

5.1 封装成 RAII 风格的抗锯齿画布

每次绘制都手动建 DIB、选位图、算覆盖率太啰嗦。我习惯封装一个AntiAliasCanvas类,构造时建 DIB,析构时自动AlphaBlend并释放资源。这样业务代码里只需要canvas.BeginDraw()和canvas.EndDraw(),中间用canvas.GetDC()拿 HDC 正常画。

class AntiAliasCanvas { public: AntiAliasCanvas(HDC hdcTarget, int w, int h) : m_target(hdcTarget), m_width(w), m_height(h) { // 创建 DIB 和内存 DC // ... } ~AntiAliasCanvas() { // 执行边缘抗锯齿处理 ApplyAntiAlias(); // AlphaBlend 到目标 DC // 释放资源 } HDC GetDC() { return m_memDC; } private: void ApplyAntiAlias() { // 边缘检测 + 覆盖率计算 } HDC m_target, m_memDC; int m_width, m_height; void* m_pBits; HBITMAP m_hDib, m_hOldBmp; };

逻辑说明:构造时完成 DIB 创建和选入,析构时先跑抗锯齿后处理,再混合到目标 DC,最后按相反顺序释放 GDI 对象。参数说明:w和h建议传客户区物理像素尺寸。这个封装把资源生命周期和抗锯齿逻辑绑在一起,避免忘记释放导致 GDI 对象泄漏。

5.2 用脏矩形减少每帧计算量

实时场景下,不是每帧所有像素都在变。维护一个脏矩形列表,只对变化区域做边缘检测和覆盖率计算。GDI 的GetClipBox可以拿到当前裁剪区域,但更可靠的是自己在业务层记录哪些图元被修改了。

// 脏矩形合并示例 RECT dirty = {0}; bool hasDirty = false; void MarkDirty(int x, int y, int w, int h) { RECT r = {x, y, x + w, y + h}; if (!hasDirty) { dirty = r; hasDirty = true; } else { UnionRect(&dirty, &dirty, &r); } }

逻辑说明:每次图形变化时调用MarkDirty,把变化区域合并到dirty。抗锯齿阶段只遍历dirty范围内的像素。参数说明:UnionRect是 Win32 API,合并两个矩形。如果脏矩形太多,可以设一个上限,超过就全屏处理。

5.3 验证抗锯齿效果的三个量化指标

光靠眼睛看不够,我一般会跑三个指标来确认效果。第一,边缘像素的 alpha 梯度是否连续,用相邻边缘像素的 alpha 差值的方差衡量,方差越小越平滑。第二,和 4x 超采样结果做 PSNR 对比,PSNR 高于 35dB 说明覆盖率估算够准。第三,单帧处理耗时,用QueryPerformanceCounter打点,1080p 局部区域控制在 5ms 以内才算实时。

// 用 QueryPerformanceCounter 测单帧抗锯齿耗时 LARGE_INTEGER freq, start, end; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&start); // ... 抗锯齿处理 ... QueryPerformanceCounter(&end); double ms = (end.QuadPart - start.QuadPart) * 1000.0 / freq.QuadPart;

逻辑说明:QueryPerformanceFrequency拿到计数频率,两次QueryPerformanceCounter的差值除以频率就是秒数,乘 1000 得毫秒。参数说明:这个计时要放在抗锯齿处理前后,不要包含AlphaBlend的耗时,因为混合是 GPU 或驱动做的,和 CPU 计算分开看。

5.4 一个我踩过的坑:别在 WM_PAINT 里做全屏抗锯齿

早期我把抗锯齿逻辑直接写在WM_PAINT里,每次窗口重绘都全屏跑一遍。结果拖动窗口时帧率掉到个位数,风扇狂转。后来改成双缓冲加脏矩形,只在WM_TIMER或者数据更新时标记脏区,WM_PAINT里只做AlphaBlend输出。这个习惯我一直保持到现在:抗锯齿是后处理,不是绘制本身,把它和绘制解耦,性能才能稳住。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

鸿蒙PDF开发实战:从文本提取到批注渲染的完整方案

鸿蒙PDF开发实战:从文本提取到批注渲染的完整方案

1. PDF能力全景&#xff1a;先看清鸿蒙给了我们什么做鸿蒙端的PDF功能&#xff0c;一开始我是拒绝的。我看了不少技术社区的帖子&#xff0c;发现很多开发者在拿到PDF相关的需求时&#xff0c;第一反应就是“能不能用WebView套一个浏览器插件”&#xff0c;结果要么交互体验割裂…

2026/10/20 22:43:03 阅读更多 →
Qt5与hidapi实战:手搓USB HID调试助手,告别串口工具

Qt5与hidapi实战:手搓USB HID调试助手,告别串口工具

简介&#xff1a;这是一份面向嵌入式与桌面开发者的USB调试工具源码包&#xff0c;基于Qt5框架与hidapi库实现&#xff0c;可在Windows 10环境下借助mingw编译运行&#xff0c;帮助开发者快速测试和调试支持HID协议的USB设备。资源共19个文件&#xff0c;约1004KB&#xff0c;包…

2026/10/20 22:41:59 阅读更多 →
用思维导图重构综合布线系统:从图纸迷宫到故障秒定位

用思维导图重构综合布线系统:从图纸迷宫到故障秒定位

1. 为什么一张图就能讲清综合布线系统&#xff1f;——从“看不懂图纸”到“一眼定位故障点”的认知跃迁你有没有过这样的经历&#xff1a;站在机房里&#xff0c;面对一整面墙的配线架、密密麻麻的跳线和标签模糊的线缆&#xff0c;手握设计图纸却像在读天书&#xff1f;图纸上…

2026/10/20 22:41:59 阅读更多 →

最新新闻

diagram-design:系统可视化设计的方法论与工程实践

diagram-design:系统可视化设计的方法论与工程实践

1. “diagram-design”不是一张图&#xff0c;而是一套系统性视觉表达方法论很多人第一次看到“diagram-design”这个词&#xff0c;下意识会把它当成“画流程图”“做PPT示意图”或者“用draw.io拖几个框连几条线”的简单操作。我最初也这么想——直到在某高校的跨学科课程设计…

2026/10/20 23:24:57 阅读更多 →
CTF实战套路:从信息收集到Shell提权的骚操作全解析

CTF实战套路:从信息收集到Shell提权的骚操作全解析

CTF里总有那么一类题&#xff0c;你说它难吧&#xff0c;考点可能一点都不深&#xff1b;你说它简单吧&#xff0c;比赛现场就是想不到。这篇文章想聊的&#xff0c;就是这些被老手们称作“骚操作”的常见套路——它们不一定在每场比赛里都会出现&#xff0c;可一旦出现&#x…

2026/10/20 23:24:57 阅读更多 →
《SHIT》期刊收稿全解析:投稿前必须明白的四个选题方向

《SHIT》期刊收稿全解析:投稿前必须明白的四个选题方向

最近收到好几个朋友的私信&#xff0c;都在问同一个事&#xff1a;《SHIT》这本期刊到底收什么稿子&#xff0c;是不是真的什么“垃圾”都收&#xff0c;投了快两个月也没回音&#xff0c;是编辑没看到还是稿子本身出了问题。我干脆把知道的情况和个人投稿经验整理成一篇&#…

2026/10/20 23:24:57 阅读更多 →
从零构建活期储蓄账目管理系统:Flask+SQLite实战指南

从零构建活期储蓄账目管理系统:Flask+SQLite实战指南

1. 从需求出发&#xff1a;为什么我会做这个活期储蓄账目管理系统先说个背景。我一直有记账的习惯&#xff0c;但记账软件换了好几款&#xff0c;总感觉差点意思——要么太重&#xff0c;理财、基金、股票全塞在一个App里&#xff0c;天天给你推送算法推荐&#xff1b;要么太轻…

2026/10/20 23:24:57 阅读更多 →
Flink多流合并算子详解:UNION、CONNECT、CoGroup与JOIN的选型与实战

Flink多流合并算子详解:UNION、CONNECT、CoGroup与JOIN的选型与实战

写了几年Flink作业&#xff0c;发现好多人在多流处理这块还是凭感觉选API。订单流来了&#xff0c;支付流来了&#xff0c;库存流来了&#xff0c;想都没想就union()一把梭&#xff0c;跑出来的数据对不上账&#xff0c;只能半夜爬起来看日志。其实Flink的多流合并算子不是简单…

2026/10/20 23:24:57 阅读更多 →
人机协同学术写作:从白屏恐惧到全流程提效的完整指南

人机协同学术写作:从白屏恐惧到全流程提效的完整指南

最近总有人问我&#xff1a;“你写论文是不是也用AI&#xff1f;”我的回答很统一&#xff1a;用&#xff0c;但不是你们想的那种用法。我不是把题目扔给AI让它替我写&#xff0c;而是把它当成一个特别能加班、特别能抬杠、特别擅长把一句废话扩成三页纸的写作搭子。真正的学术…

2026/10/20 23:23:57 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →