AS3涂鸦变色实现:ColorTransform整体换色与Graphics局部笔刷
这周翻旧项目把之前做的Flash互动页面又看了一遍有个功能让我印象特别深用户拿着鼠标在场景里的卡通形象上随意比划被扫过的区域就变成选中的颜色看起来就像拿画笔在墙上涂鸦。当时用的技术栈是AS3核心问题拆到底只有一个怎么改变元件整体颜色同时还要让涂色这个动作足够自然、跟手、不穿帮。这篇文章就把当时的完整思路写出来。整个实现分成两层先用ColorTransform解决整体换色再在上面叠加一个用Graphics画的涂鸦层解决局部涂画。如果你分不清整体换色和局部涂画为什么是两件事建议先把第一段读完这会直接影响后面的方案选型。1. 先把需求掰开你想要的到底是变色还是涂鸦1.1 一个需求两种理解遇到改变元件颜色的需求第一反应往往是ColorTransform一行代码就能让整个元件换色。可一旦需求里出现涂鸦两个字事情就变了——涂鸦意味着用户的操作是连续的、局部的、即时的而不是一次性把整个元件换个色。我在某个活动项目里就吃过这个亏。最初给演示的是点一下按钮整个卡通形象瞬间变蓝对方看完说我要的不是油漆桶效果是拿画笔一笔一笔涂出来的感觉。这句话让我意识到改颜色这个动作本身只是技术问题但怎么涂才是产品体验的核心。这个差别不只是好看不好看。整体变色是一个瞬时状态切换状态从A变成B结束。涂鸦是一个持续绘画过程用户按住鼠标经过的每个点都产生颜色叠加松开鼠标才结束一次笔画。方案选错返工成本会很高。1.2 涂鸦体验的四个基本要求做了几轮调优后我总结出模拟涂鸦必须满足四点缺一个就会让人觉得假连续性鼠标移动的轨迹不能断快速划过时也不能出现断线或跳点。实时性笔迹必须立刻显示延迟超过一两帧手感就废了。局部性涂到的区域变颜色没涂到的保持原样这是涂鸦和整体变色最本质的区别。可逆性用户涂错了要能撤销即使在简单Demo里撤销也是信任感的来源。这四个要求决定了技术选型的方向。整体变色只能满足第三点的反面局部性恰恰是它不具备的。所以我的做法不是二选一而是把两个技术栈组合起来底层元件负责整体状态上层覆盖层负责局部笔迹。2. 三条改色路线ColorTransform、Graphics覆盖层与BitmapData逐像素2.1 路线AColorTransform整体换色AS3里最直接的改色方式就是给显示对象的transform.colorTransform赋值一个ColorTransform对象。它本质上是把元件渲染时的颜色分量做一次线性变换通过乘法器和偏移量控制最终输出的红绿蓝值。这条路线的优点是开销极小一个赋值操作就能让整个元件重新着色不需要遍历子对象不需要处理绘制逻辑。缺点是它作用于整个显示对象树无法做到只涂一半。2.2 路线BGraphics覆盖层刷色这是模拟涂鸦最顺手的一种方式。做法是在目标元件上方放一个透明Shape用户移动鼠标时在Shape.graphics上画圆或画线圆和线就是颜料。由于Shape是独立于目标元件的涂上去的颜色天然只影响被画到的区域完全符合涂鸦的局部性要求。而且Graphics的绘制效率很高画几百个圆不会明显掉帧。路线B的局限是它只是叠加了一层颜色并没有真正改变目标元件本身。如果目标元件内部还有动画、边框、文字这些部分是无法通过覆盖层自然融合的需要额外设计。2.3 路线CBitmapData逐像素最硬核的方案把元件绘制到BitmapData上然后逐像素修改颜色。这种方式自由度最高可以实现渐变、透明度混合、纹理填充但代价也最大——逐像素操作在纯AS3里跑得很慢尤其当元件尺寸大、需实时响应时CPU压力会非常明显。我实测过一个500x500的元件全量像素遍历一次耗时约几十毫秒看起来能接受但如果鼠标移动每秒产生几十个点位每个点位都触发一次全像素扫描卡顿是必然的。2.4 实测对比与选型结论把三条路线放一起对比各自的定位就很清楚了方案性能局部性开发成本适用场景ColorTransform极高无极低整体换色、状态切换Graphics覆盖层高强低实时涂鸦、画笔模拟BitmapData逐像素低最强高纹理填充、滤镜特效我的选型结论是主交互用Graphics覆盖层快捷功能用ColorTransform。整体换色解决一键把全部涂成红色这类需求覆盖层解决一笔一笔涂的需求。BitmapData只在需要保存最终成品或做撤销快照时使用。后面所有代码都是按这个思路来的。3. 核心实现一ColorTransform整体变色从色值到参数的换算3.1 搭一个干净的测试场景先做一个可复现的Demo。我习惯用一个MovieClip作为目标元件内部画一个填充了白色的圆形再加上一个简单边框方便观察颜色变化。var target:MovieClip new MovieClip(); target.graphics.beginFill(0xFFFFFF); target.graphics.drawCircle(0, 0, 80); target.graphics.endFill(); target.graphics.lineStyle(2, 0x666666); target.graphics.drawCircle(0, 0, 80); addChild(target); target.x stage.stageWidth / 2; target.y stage.stageHeight / 2;这里的关键点内部填充色必须是纯白。为什么因为ColorTransform的计算是线性的白色255,255,255是乘法器换算时的最理想基准值能从目标色值反推出一组干净的参数。如果原始填充色不是白色颜色的叠加结果就不直观。3.2 multiplier 和 offset 到底怎么用ColorTransform的构造函数长这样public function ColorTransform( redMultiplier:Number 1, greenMultiplier:Number 1, blueMultiplier:Number 1, alphaMultiplier:Number 1, redOffset:Number 0, greenOffset:Number 0, blueOffset:Number 0, alphaOffset:Number 0 )计算规则是最终值 原始值 × multiplier offset。每个颜色通道独立运算最后再合并输出。举个例子。目标元件的填充色是白色红255、绿255、蓝255。如果我想把它变成纯红色很简单红色通道保持原样绿色和蓝色通道归零。redMultiplier 1红色保持255greenMultiplier 0绿色从255变0blueMultiplier 0蓝色从255变0这样元件就变成了纯红。如果把redOffset 128、redMultiplier 0红色就会变成固定的128即中等亮度红色。3.3 目标色到参数的换算公式实际开发中用户是从调色板里选颜色拿到的是一个uint类型的色值比如0xFF6600。要把它转成ColorTransform参数我基于填充色为白色的约定做了下边这组换算function transformToColor(target:DisplayObject, targetColor:uint):void { var r:Number (targetColor 16) 0xFF; var g:Number (targetColor 8) 0xFF; var b:Number targetColor 0xFF; var ct:ColorTransform new ColorTransform( r / 255, g / 255, b / 255, 1, 0, 0, 0, 0 ); target.transform.colorTransform ct; }因为填充是白色r/255得到乘法器后白色份量的256种取值刚好映射到目标颜色的256种取值损耗为零。如果填充色不是白色而是浅灰比如0xCCCCCC乘法器运算后有些颜色会偏暗这就是颜色发灰问题的来源之一后面专门讲。3.4 一键恢复原色有变色就得有还原。把ColorTransform重置为默认值即可function resetColor(target:DisplayObject):void { target.transform.colorTransform new ColorTransform( 1, 1, 1, 1, 0, 0, 0, 0 ); }注意不能用target.transform.colorTransform null那会把显示对象抛向未知状态我曾经这么写过一次结果整个元件消失了排查了半天。恢复原色用默认构造参数最省心。到这里ColorTransform这条线就通了。它解决整个元件瞬间换色的问题但离涂鸦还差一层交互和一层局部绘制。别急下一步就把画笔接进来。4. 核心实现二Graphics覆盖层把变色升级为涂鸦4.1 画布分层怎么铺才不会挡交互涂鸦的交互模型是鼠标按下开始画拖动过程持续画松开结束。这里有个容易被忽略的细节——你监听事件的对象不一定是你绘制颜色的对象。我的做法是创建一个透明的Shape作为画布把它放在目标元件上方并且把mouseEnabled设为false。这样鼠标事件会穿透画布落到目标元件或舞台容器上而颜色仍然画在画布里互不干扰。var canvas:Shape new Shape(); canvas.mouseEnabled false; addChild(canvas); // 保证canvas在target之上这个技巧帮我省掉了几次重写。如果直接把事件绑在画布上由于画布默认不接收鼠标事件的区域和它实际宽度一致反而容易在工具条、按钮等地方发生误判。4.2 涂鸦刷子参数与绘制逻辑涂鸦刷子本质上就是一系列圆。鼠标每移动一小段距离我就画一个新圆。为了让相邻圆之间看不出锯齿感圆与圆之间的间距必须小于圆的直径。刷子的核心参数有三个brushSize圆的半径brushColor当前选中的颜色brushAlpha颜料透明度通常设为1模拟不透明笔刷private var brushSize:Number 12; private var brushColor:uint 0xFF0000; private var brushAlpha:Number 1; function drawDot(localX:Number, localY:Number):void { canvas.graphics.beginFill(brushColor, brushAlpha); canvas.graphics.drawCircle(localX, localY, brushSize); canvas.graphics.endFill(); }这里我用了drawCircle而不是lineTo。两者的区别在于lineTo画的是路径需要维护一根连续的笔触方向容易在鼠标快速拐弯时出现锋利的折线drawCircle则是一个个独立的点只要点够密视觉上自然连成平滑曲线而且实现思路更简单。4.3 mouseDown / mouseMove / mouseUp 三段式状态机涂鸦交互用三段式状态实现是最稳妥的写法。用一个布尔量isDrawing控制当前是否处于绘画状态。stage.addEventListener(MouseEvent.MOUSE_DOWN, onBrushDown); stage.addEventListener(MouseEvent.MOUSE_MOVE, onBrushMove); stage.addEventListener(MouseEvent.MOUSE_UP, onBrushUp); private function onBrushDown(e:MouseEvent):void { if (!hitTestTarget(e.stageX, e.stageY)) return; isDrawing true; drawDot(stageToLocalX(e.stageX), stageToLocalY(e.stageY)); } private function onBrushMove(e:MouseEvent):void { if (!isDrawing) return; drawDot(stageToLocalX(e.stageX), stageToLocalY(e.stageY)); } private function onBrushUp(e:MouseEvent):void { isDrawing false; }我建议把事件绑定在stage而不是目标元件上。原因是如果用户鼠标快速滑出元件范围元件自身的MOUSE_OUT会提前打断绘画状态画出一条突然中断的线而stage上的事件能保证在整个拖动过程中持续响应直到松开鼠标。hitTestTarget用于判断起始点是否落在目标元件内部避免用户从空白处开始画结果画到空气里。4.4 坐标换算缩放和旋转下的全局转本地很多Demo里目标元件都是固定的位置、角度、缩放都不变所以直接用mouseX/mouseY就能绘制。但真实项目里元件可能被设置了旋转角度也可能响应了舞台缩放这时候直接用全局坐标画会出现笔迹漂移。正确做法是用globalToLocal把舞台坐标转换成画布本地坐标function getLocalFromStage(e:MouseEvent):Point { var global:Point new Point(e.stageX, e.stageY); return canvas.globalToLocal(global); }globalToLocal会同时处理好元件的scaleX、scaleY和rotation带来的坐标变化。我一直用这个方法省掉了大量手工换算的麻烦。4.5 支持撤销的简易快照方案涂鸦功能上线后用户涂错了想反悔这时候我用了两种策略组合。第一种是动作栈每次MOUSE_UP时把这一次笔画里所有圆的位置和颜色记录进一个数组。撤销时从画布上把所有记录过的笔画清掉再重新绘制除了最后一笔之外的所有内容。这种策略内存开销小但绘制时间长当笔画多达几百笔时会卡顿。第二种是位图快照每次MOUSE_UP时把当前画布内容用BitmapData.draw保存到内存中。撤销时直接用上一张快照覆盖当前画布。这种策略绘制快但内存占用随笔画数线性增长。我实际用到的是限制快照数量的改进版最多保存10张快照超出后从最旧的开始删除。private var undoStack:Array []; function saveSnapshot():void { var bmpData:BitmapData new BitmapData(canvas.width, canvas.height, true, 0x000000); bmpData.draw(canvas); undoStack.push(bmpData); if (undoStack.length 10) { var removed:BitmapData undoStack.shift() as BitmapData; removed.dispose(); } } function undo():void { if (undoStack.length 0) return; var prev:BitmapData undoStack.pop() as BitmapData; canvas.graphics.clear(); canvas.graphics.beginBitmapFill(prev); canvas.graphics.drawRect(0, 0, canvas.width, canvas.height); canvas.graphics.endFill(); }用beginBitmapFill把快照画回去的思路比逐像素复制快很多而且代码量也少。注意BitmapData用完要dispose不然内存会一直涨。到这里一个完整的模拟涂鸦功能已经能跑了。但能跑和能上线之间还有一段距离下面这部分的坑我几乎每个都踩过。5. 我踩过的坑颜色发灰、反复涂抹掉帧、点不中元件5.1 colorTransform把边框文字也染色了ColorTransform作用于整个显示对象树。这意味着不只是填充区域变色元件内部的边框、文字、图标全部跟着变色。某次测试时我把一个白色卡通形象染成黄色结果它眼睛里的高光、嘴边的描边全变成了黄色观感非常怪。解决思路是把可涂色区域和不可涂色区域在显示层级上分开。我是这样处理的把填充主体做成一个独立的子元件ColorTransform只作用于这个子元件描边、五官、装饰放另一层不参与变色。这样既保留了整体变色又不会把不该染的地方染掉。5.2 涂色卡的真相重绘压力与cacheAsBitmap涂鸦过程中如果鼠标移动很快MOUSE_MOVE事件会非常密集我在某次测试里一秒钟触发了上百次drawCircle。理论上每个圆都很轻但实际发现帧率明显下降。查来查去问题出在重绘区域计算上。Flash的渲染器在检测到画布内容变化时会重新计算画布脏区并触发重绘而画布又叠在目标元件上方导致目标元件也被迫参与重绘。解决办法有两个给画布设置cacheAsBitmap true让画布先渲染成位图再叠加上去减少合成压力。限制绘制频率。当鼠标移动距离小于minStep时不画新的圆只有位移超过阈值才画。这样既保证轨迹连续又大幅降低事件处理次数。private var lastPoint:Point; private var minStep:Number 3; function drawDot(localX:Number, localY:Number):void { var now:Point new Point(localX, localY); if (lastPoint Point.distance(now, lastPoint) minStep) return; canvas.graphics.beginFill(brushColor, brushAlpha); canvas.graphics.drawCircle(localX, localY, brushSize); canvas.graphics.endFill(); lastPoint now; }实测下来minStep 3到5像素之间轨迹看起来还是连续的但事件处理量能减少一半以上。5.3 覆盖层抢走了鼠标事件前面说过我把画布的mouseEnabled设成了false但如果你忘了这一步画布会像一堵透明的墙把所有鼠标事件挡在自己身上。最典型的现象是目标元件上的MOUSE_DOWN触发了但MOUSE_MOVE事件在画布上不触发因为事件目标变成了画布本身。更隐蔽的情况是画布上已经画了不透明颜色用户再次点击时鼠标事件被画布上那块不透明区域拦截导致无法继续操作下方元件。宝可孟就发生了必须把画布的mouseEnabled和mouseChildren都设为false同时让所有的按钮、工具条都放在画布之上。5.4 动态生成元件的命中测试问题最后说一下命中测试。由于涂鸦功能用到的是舞台级事件所以判断用户是否点中了元件必须手动处理。早期我用的是hitTestPoint把舞台坐标传给目标元件结果在元件经过缩放或旋转后频繁失灵。原因是hitTestPoint的第二个参数shapeFlag如果设为false只检测矩形边界不检测实际形状。给一个旋转45度的元件做命中测试边界框会明显大于实际可视区点空气也算命中。正确做法是function hitTestTarget(stageX:Number, stageY:Number):Boolean { var local:Point target.globalToLocal(new Point(stageX, stageY)); return target.hitTestPoint(local.x, local.y, true); }先把舞台坐标转成元件的本地坐标再用shapeFlag true做真实形状检测。这个改动看起来很小但直接决定了用户能不能指哪打哪。最后再分享一个小技巧如果目标元件是一个包含多帧动画的角色涂鸦颜色会随着帧切换而消失因为每帧的画面都是新绘制的透明画布上已经涂的颜色依然在但元件本身换了一帧面目全非。这种情况下我一般把涂鸦画布做成目标元件的子对象让画布跟着元件的位移、旋转一起动帧切换只影响元件内部的内容画布上的笔迹保留完整。这个细节能省去很多后续同步的麻烦。

相关新闻

永磁同步电机滑模+预测控制方案:从原理到参数整定

永磁同步电机滑模+预测控制方案:从原理到参数整定

电机控制这个方向,论文越看越深,工程上能落地的方案其实就那几条路。我最近完整啃下来一套“永磁同步电机(PMSM)转速外环用非奇异快速终端滑模、电流内环用预测控制”的方案,从数学模型推演、仿真搭建到参数整定都走了…

2026/10/17 14:05:30 阅读更多 →
WPF DataGrid复杂列样式:图标+状态+下拉+Tooltip+编辑态五合一实现

WPF DataGrid复杂列样式:图标+状态+下拉+Tooltip+编辑态五合一实现

简介:本资源是一份面向WPF中高级开发者的实用型UI定制实践案例,聚焦解决DataGrid默认列样式无法满足复杂业务展示需求的痛点,如单元格内多字段组合呈现、自定义排版及交互控件嵌入等典型场景。压缩包共15个文件,含8个C#逻辑文件&a…

2026/10/16 8:16:22 阅读更多 →
Epoll 高并发实战:ET模式、事件循环与内核协同设计

Epoll 高并发实战:ET模式、事件循环与内核协同设计

1. 为什么 Epoll 不是“另一个 select”,而是 Linux 高并发网络服务的底层支点很多人第一次接触 Epoll,是在某次面试被问到“select/poll/epoll 区别”时临时背下的三行对比:select 有 1024 文件描述符限制,poll 没上限但每次都要…

2026/10/17 14:34:37 阅读更多 →

最新新闻

codex针对java+vue的Prompt提示词:用TaoToken统一Key跑通前后端联调

codex针对java+vue的Prompt提示词:用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/17 15:00:39 阅读更多 →
Oracle 11g 升级 19C 实战避坑:DBUA 报错、RMAN 恢复与时区版本全解析

Oracle 11g 升级 19C 实战避坑:DBUA 报错、RMAN 恢复与时区版本全解析

简介:这份Oracle 11g到19C数据库升级详尽指导手册,面向具备一定运维能力的数据库管理员(DBA)及运维工程师,聚焦利用DBUA工具将11g单机数据库安全迁移至19C的完整流程。内容涵盖前期备份与恢复、升级路线选择、环境说明…

2026/10/17 15:00:39 阅读更多 →
ZooKeeper节点类型详解:持久、临时、顺序节点的原理与实战避坑

ZooKeeper节点类型详解:持久、临时、顺序节点的原理与实战避坑

我这几年在分布式系统上踩的坑,有一大半都跟ZooKeeper的节点类型有关。不管是做分布式锁、服务注册发现,还是元数据存储,选错了节点类型,轻则功能异常,重则线上事故。今天就把这四种节点的特点、原理和使用场景彻底讲透…

2026/10/17 15:00:39 阅读更多 →
好写作AI:期刊论文选题到投稿全流程实操指南

好写作AI:期刊论文选题到投稿全流程实操指南

凌晨三点,对着屏幕上那块光标闪了一晚上的空白文档,手边的咖啡已经第三杯了。讲实话,这种场景在科研生活里太常见了:Introduction写不出逻辑链、文献综述堆了几十篇却不知道从哪句话开始、明明实验数据都齐了结果讨论部分憋不出来…

2026/10/17 15:00:39 阅读更多 →
Spring Boot内嵌Tomcat启动链路:原理、定制与避坑实战

Spring Boot内嵌Tomcat启动链路:原理、定制与避坑实战

简介:《Spring Boot启动过程(四)之内嵌Tomcat启动》是一份面向中高级Spring Boot开发者的PDF解析文档,帮助厘清启动阶段内嵌Web容器的创建、配置与初始化链路。文档以源码调用顺序为主线,先解释createEmbeddedServletC…

2026/10/17 15:00:39 阅读更多 →
分布式计算与并行计算区别详解:选型与实战指南

分布式计算与并行计算区别详解:选型与实战指南

我一直觉得,很多人一听到“分布式计算”和“并行计算”,第一反应是“这不差不多嘛,都是把任务拆开同时算”。实际上这两个概念在大数据处理里的定位差异非常大,用错场景轻则性能没提升,重则整套架构白搭。这篇文章我就…

2026/10/17 14:59:38 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 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/16 21:54:38 阅读更多 →
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/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →