主题
截图与图像处理
本文引用的源码文件
本文引用的文件
目录
引言
本文面向“截图与图像处理”能力,系统性梳理本仓库在 Chrome 扩展(Manifest V3)中的实现方案,覆盖以下主题:
- 页面截图:全页面捕获、可视区域截图、指定元素截图、高质量渲染选项。
- 区域选择截图:鼠标拖拽选择、矩形区域定义、实时预览、截图结果处理。
- 图像识别集成:OCR/视觉模型调用、图像格式转换、尺寸优化、质量压缩。
- 图片预览处理:缩略图生成、懒加载优化、全屏查看、批量管理。
- Canvas API 使用示例与算法细节。
- 跨浏览器兼容性、内存管理与性能优化策略。
- 与 AI 视觉模型的集成方式与最佳实践。
本项目采用双进程架构:Chrome 扩展端(src/)+ 独立本地代理端 Agent(Node.js)。截图与图像处理主要发生在扩展端 background、content script 与 side panel 之间,必要时通过 HTTP/WebSocket 与 Agent 交互。
项目结构
截图与图像处理相关代码分布在以下模块:
- background:负责底层截图、下载、视觉模型调用与流式响应处理。
- content script:提供高级工具(如指定元素截图)、区域选择入口。
- side panel:提供用户交互(全页/区域截图按钮)、图片裁剪、预览与编辑。
- shared:通用快照渲染逻辑(与截图无关但体现结构化输出能力)。
graph TB subgraph "扩展端" SP["Side Panel<br/>image-helpers.js / image-preview.js"] BG["Background<br/>index.js / tool-executor.js / media-tools.js / tool-screenshot.js"] CS["Content Script<br/>advanced-tools.js / index.js"] end SP --> |消息 CAPTURE_TAB / START_REGION_SELECTION| BG CS --> |消息 CAPTURE_ELEMENT_SCREENSHOT| BG BG --> |HTTP/SSE| VisionAPI["AI 视觉模型 API"] BG --> |downloads API| LocalDisk["本地磁盘"]
图表来源
- src/background/index.js#L1289-L1330
- src/background/tool-executor.js#L1350-L1441
- src/background/tools/media-tools.js#L91-L114
- src/background/tool-screenshot.js#L8-L23
- src/content/advanced-tools.js#L323-L353
- src/content/index.js#L171-L181
- src/side_panel/image-helpers.js#L150-L269
- src/side_panel/image-preview.js#L345-L439
章节来源
- src/background/index.js#L1289-L1330
- src/background/tool-executor.js#L1350-L1441
- src/background/tools/media-tools.js#L91-L114
- src/background/tool-screenshot.js#L8-L23
- src/content/advanced-tools.js#L323-L353
- src/content/index.js#L171-L181
- src/side_panel/image-helpers.js#L150-L269
- src/side_panel/image-preview.js#L345-L439
核心组件
- 背景截图与下载
- 统一消息路由:CAPTURE_TAB、CAPTURE_TAB_FROM_PAGE、CAPTURE_REGION_FROM_PAGE。
- 工具函数:triggerScreenshotDownload 触发 downloads API 保存截图。
- 可视化截图工具
- capture_page 工具定义:支持 action=download/analyze/both、format、quality、visionMaxDim、visionQuality。
- 实际执行:captureVisibleTab + OffscreenCanvas 压缩 + 视觉模型分析。
- Content Script 高级工具
- screenshotElement:基于 getBoundingClientRect 获取元素矩形并请求后台截图。
- START_REGION_SELECTION:启动区域选择流程。
- Side Panel 图片辅助
- captureFullPageScreenshot:发送 CAPTURE_TAB,接收 dataUrl 后压缩并附加到输入区。
- captureRegionScreenshot:先 START_REGION_SELECTION 得到 rect,再截取可见区域并裁剪。
- cropImage:Canvas 按 DPR 缩放裁剪。
- handlePageScreenshotResult:处理快捷键截图结果(全页或区域)。
- 图片预览与编辑
- compressAndAttachImage:根据原图尺寸动态计算压缩参数,生成缩略图与压缩图。
- openImagePreview:全屏查看、缩放、平移、多图切换、键盘导航。
- 标注编辑:画笔、橡皮擦、矩形、椭圆、箭头、直线;撤销栈;合成标注图。
章节来源
- src/background/index.js#L1289-L1330
- src/background/tool-screenshot.js#L8-L23
- src/background/tools/media-tools.js#L91-L114
- src/background/tool-executor.js#L1350-L1441
- src/content/advanced-tools.js#L323-L353
- src/content/index.js#L171-L181
- src/side_panel/image-helpers.js#L150-L269
- src/side_panel/image-preview.js#L345-L439
- src/side_panel/image-preview.js#L800-L1063
架构总览
截图与图像处理的关键路径如下:
- 用户从 Side Panel 点击“全页截图”或“区域截图”。
- Side Panel 向 Background 发送消息(CAPTURE_TAB 或 START_REGION_SELECTION)。
- Background 调用 chrome.tabs.captureVisibleTab 获取 dataUrl。
- 若为 analyze/both,则进行图像压缩与视觉模型调用;若为 download/both,则触发下载。
- 最终将截图数据返回给 Side Panel,进入图片附件与预览流程。
sequenceDiagram
participant SP as "Side Panel"
participant BG as "Background"
participant CS as "Content Script"
participant Vision as "AI 视觉模型 API"
SP->>BG : "CAPTURE_TAB"
BG-->>SP : "{dataUrl}"
SP->>SP : "compressAndAttachImage(dataUrl)"
Note over SP,BG : "区域截图"
SP->>CS : "START_REGION_SELECTION"
CS-->>SP : "{x,y,width,height}"
SP->>BG : "CAPTURE_TAB"
BG-->>SP : "{dataUrl}"
SP->>SP : "cropImage(dataUrl, rect)"
Note over BG,Vision : "视觉分析可选"
BG->>Vision : "POST /chat/completions (SSE/JSON)"
Vision-->>BG : "分析文本"
图表来源
- src/background/index.js#L1289-L1330
- src/content/index.js#L171-L181
- src/side_panel/image-helpers.js#L150-L269
- src/background/tool-executor.js#L1489-L1583
详细组件分析
页面截图能力
- 全页面捕获
- Side Panel 发送 CAPTURE_TAB,Background 返回 dataUrl。
- 适用于快速截图并作为图片附件。
- 可视区域截图
- 通过 chrome.tabs.captureVisibleTab 直接获取当前窗口可见区域。
- 支持 format(jpeg/png)与 quality 参数。
- 指定元素截图
- Content Script 通过 getBoundingClientRect 获取元素矩形,发送 CAPTURE_ELEMENT_SCREENSHOT。
- Background 可据此对目标区域进行截图(由上层工具编排)。
- 高质量渲染选项
- 工具定义中支持 format、quality、visionMaxDim、visionQuality。
- 视觉分析前使用 OffscreenCanvas 压缩,控制最大边长与 JPEG 质量。
flowchart TD
Start(["开始"]) --> Mode{"截图模式"}
Mode --> |全页| Full["发送 CAPTURE_TAB"]
Mode --> |可视区域| Visible["captureVisibleTab(format, quality)"]
Mode --> |指定元素| Element["getBoundingClientRect -> CAPTURE_ELEMENT_SCREENSHOT"]
Full --> Result["返回 dataUrl"]
Visible --> Result
Element --> Result
Result --> End(["结束"])
图表来源
- src/background/index.js#L1289-L1330
- src/background/tool-executor.js#L1350-L1441
- src/content/advanced-tools.js#L323-L353
章节来源
- src/background/index.js#L1289-L1330
- src/background/tool-executor.js#L1350-L1441
- src/background/tools/media-tools.js#L91-L114
- src/content/advanced-tools.js#L323-L353
区域选择截图机制
- 鼠标拖拽选择
- Side Panel 向 Content Script 发送 START_REGION_SELECTION。
- Content Script 返回 {x, y, width, height} 视口坐标。
- 矩形区域定义
- 使用 getBoundingClientRect 或自定义选择器计算矩形。
- 实时预览
- 在 Content Script 中绘制选择框(参考 selection-toolbar 样式),并在 Side Panel 显示提示。
- 截图结果处理
- 先截取整个可见区域,再用 Canvas 按 DPR 缩放裁剪。
- 转换为 Blob 后进入 compressAndAttachImage 流程。
sequenceDiagram
participant SP as "Side Panel"
participant CS as "Content Script"
participant BG as "Background"
SP->>CS : "START_REGION_SELECTION"
CS-->>SP : "{x,y,width,height}"
SP->>BG : "CAPTURE_TAB"
BG-->>SP : "{dataUrl}"
SP->>SP : "cropImage(dataUrl, rect)"
SP->>SP : "compressAndAttachImage(blob)"
图表来源
章节来源
图像识别集成方案
- OCR 服务调用
- 读取 imageApiBase、imageApiKey、imageModelName、streamEnabled。
- 构造 messages,包含 text 与 image_url(base64 dataUrl)。
- 支持流式(SSE)与非流式两种响应模式。
- 图像格式转换
- 使用 createImageBitmap + OffscreenCanvas 将 dataUrl 转为 Blob,再转回 dataUrl。
- 尺寸优化与质量压缩
- 根据 visionMaxDim 与 visionQuality 调整最大边长与 JPEG 质量。
- 失败时回退原始截图。
- 超时与错误处理
- 60 秒超时 AbortController。
- 空结果或网络异常时返回友好提示。
flowchart TD
A["原始截图 dataUrl"] --> B["fetch + blob + createImageBitmap"]
B --> C{"是否超过 maxDim?"}
C --> |是| D["按比例缩放至 maxDim"]
C --> |否| E["保持原尺寸"]
D --> F["OffscreenCanvas.drawImage"]
E --> F
F --> G["convertToBlob(JPEG, quality)"]
G --> H["FileReader.readAsDataURL"]
H --> I["压缩后的 dataUrl"]
图表来源
章节来源
图片预览处理功能
- 缩略图生成
- calculateCompressionParams 根据原图尺寸动态决定 targetWidth/targetHeight/quality。
- 使用 Canvas 绘制并按 quality 导出 JPEG。
- 懒加载优化
- 缩略图仅展示 originalUrl 或 compressedUrl,避免重复解码大图。
- 全屏查看
- openImagePreview 支持缩放、平移、双击 2x、滚轮缩放、键盘导航。
- 批量管理
- collectPreviewImages 收集同组图片,支持上一张/下一张循环切换。
- renderImagePreviewsFromChat 渲染缩略图列表,支持移除操作。
classDiagram
class ImagePreview {
+openImagePreview(dataUrl, sourceElement)
+calculateCompressionParams(width, height)
+compressAndAttachImage(blob)
+renderImagePreviewsFromChat()
+buildUserContent(text)
+stripImagesFromContent(content)
}
class State {
+attachedImages
+enableImageInput
}
ImagePreview --> State : "读写附件状态"
图表来源
- src/side_panel/image-preview.js#L345-L439
- src/side_panel/image-preview.js#L120-L152
- src/side_panel/image-preview.js#L444-L512
章节来源
- src/side_panel/image-preview.js#L345-L439
- src/side_panel/image-preview.js#L120-L152
- src/side_panel/image-preview.js#L444-L512
Canvas API 使用示例与算法细节
- 裁剪图片
- 考虑 devicePixelRatio,sx/sy/sw/sh 乘以 dpr。
- ctx.drawImage(img, sx, sy, sw, sh, 0, 0, sw, sh)。
- toDataURL('image/jpeg', 0.85) 输出 JPEG。
- 压缩图片
- createImageBitmap + OffscreenCanvas + convertToBlob({type:'image/jpeg', quality})。
- 标注合成
- editCanvas 与 previewCanvas 叠加绘制,确认后合成到 compositeCanvas(naturalWidth/naturalHeight)。
- 缩放比例 scaleX/scaleY 映射标注到原图尺寸。
flowchart TD S["开始裁剪/压缩"] --> Load["Image/Blob 加载"] Load --> DPR["计算 dpr = window.devicePixelRatio || 1"] DPR --> Draw["ctx.drawImage(...)"] Draw --> Export["toDataURL / convertToBlob"] Export --> Done["结束"]
图表来源
- src/side_panel/image-helpers.js#L223-L245
- src/background/tool-executor.js#L1443-L1483
- src/side_panel/image-preview.js#L1001-L1054
章节来源
- src/side_panel/image-helpers.js#L223-L245
- src/background/tool-executor.js#L1443-L1483
- src/side_panel/image-preview.js#L1001-L1054
依赖关系分析
- 模块耦合
- Side Panel 依赖 Background 的消息通道(CAPTURE_TAB、START_REGION_SELECTION)。
- Content Script 暴露 START_REGION_SELECTION 与 QRCODE 等异步工具。
- Background 依赖 chrome.* APIs(tabs、downloads、storage)与外部视觉模型 API。
- 外部依赖
- 视觉模型 API:支持 SSE 流式与非流式 JSON。
- Chrome Downloads API:用于本地保存截图。
- 潜在循环依赖
- 无直接循环导入;消息传递解耦各模块职责。
graph LR SP["side_panel/image-helpers.js"] --> BG["background/index.js"] SP --> IMG["side_panel/image-preview.js"] CS["content/advanced-tools.js"] --> BG BG --> DL["background/tool-screenshot.js"] BG --> EXE["background/tool-executor.js"] EXE --> Vision["AI 视觉模型 API"]
图表来源
- src/side_panel/image-helpers.js#L150-L269
- src/background/index.js#L1289-L1330
- src/background/tool-screenshot.js#L8-L23
- src/background/tool-executor.js#L1350-L1441
- src/content/advanced-tools.js#L323-L353
章节来源
- src/side_panel/image-helpers.js#L150-L269
- src/background/index.js#L1289-L1330
- src/background/tool-screenshot.js#L8-L23
- src/background/tool-executor.js#L1350-L1441
- src/content/advanced-tools.js#L323-L353
性能与内存优化
- OffscreenCanvas 压缩
- 在 Background 中使用 OffscreenCanvas 将截图压缩为 JPEG,减少传输与上下文大小。
- 动态压缩参数
- Side Panel 的 calculateCompressionParams 根据原图尺寸自动选择目标尺寸与质量,降低 Token 消耗。
- DPR 适配
- 裁剪时使用 devicePixelRatio,确保高 DPI 屏幕下裁剪精度。
- 流式响应
- 视觉模型 SSE 流式读取,避免长时间阻塞,提升用户体验。
- 内存释放
- URL.createObjectURL 后立即 revokeObjectURL,避免内存泄漏。
- 降级策略
- 压缩失败时回退原始截图;QRCode 库缺失时使用 SVG 降级方案。
[本节为通用指导,不直接分析具体文件]
故障排查指南
- 截图失败
- 检查 Background 的 CAPTURE_TAB/CAPTURE_TAB_FROM_PAGE 分支是否正确返回 dataUrl。
- 确认当前标签页可用且未被浏览器限制。
- 区域截图失败
- 确认 Content Script 的 START_REGION_SELECTION 已正确返回矩形坐标。
- 检查 cropImage 的 DPR 计算与 Canvas 绘制是否正常。
- 视觉模型分析失败
- 检查 imageApiBase、imageApiKey、imageModelName 配置。
- 确认 SSE 流式或非流式响应解析逻辑。
- 注意 60 秒超时与 AbortError 处理。
- 下载失败
- 检查 triggerScreenshotDownload 的 downloads API 调用与 lastError。
章节来源
- src/background/index.js#L1289-L1330
- src/background/tool-executor.js#L1489-L1583
- src/background/tool-screenshot.js#L8-L23
- src/side_panel/image-helpers.js#L172-L245
结论
本仓库在 Chrome 扩展端实现了完整的截图与图像处理能力:
- 通过 Background 统一消息路由与 chrome.tabs.captureVisibleTab 完成全页/可视区域截图。
- 借助 Content Script 的高级工具与区域选择机制,实现精准的元素与区域截图。
- 利用 OffscreenCanvas 与动态压缩参数,在保证质量的前提下显著降低图像体积。
- 集成 AI 视觉模型,支持流式响应与超时控制,提供智能分析能力。
- Side Panel 的图片预览与编辑功能完善,支持缩略图、全屏查看、批量管理与标注合成。
- 整体架构清晰、模块解耦良好,具备较强的可扩展性与可维护性。
[本节为总结性内容,不直接分析具体文件]
附录:Canvas API 使用示例与最佳实践
- 裁剪示例
- 使用 Image 加载 dataUrl,创建 Canvas,设置宽高为 rect.widthdpr 与 rect.heightdpr。
- ctx.drawImage(img, sx, sy, sw, sh, 0, 0, sw, sh),导出 JPEG。
- 压缩示例
- fetch(dataUrl).then(res=>res.blob()).then(blob=>createImageBitmap(blob))。
- OffscreenCanvas(width,height).getContext('2d').drawImage(bitmap,...)。
- canvas.convertToBlob({type:'image/jpeg', quality})。
- 标注合成示例
- 将 editCanvas 与 previewCanvas 绘制到 compositeCanvas(naturalWidth/naturalHeight)。
- 使用 ctx.scale(scaleX, scaleY) 映射标注到原图尺寸。
- 最佳实践
- 始终考虑 devicePixelRatio,保证高 DPI 设备下的清晰度。
- 及时释放 URL 对象,避免内存泄漏。
- 对大图像进行尺寸与质量双重优化,平衡清晰度与性能。
- 对视觉模型调用增加超时与重试机制,提升鲁棒性。
[本节为通用指导,不直接分析具体文件]