我给豆包写了个去水印插件,顺手解决了一个痛点

15 阅读2分钟

之前在刷豆包的时候看到一个挺有意思的图片,想保存下来发朋友圈,结果下载下来发现右下角带了个水印,logo +文字,体验非常"字节跳动"。 作为一个开发者,我的第一反应不是去淘宝找人P,而是——能不能写个脚本自动去掉? 痛点分析 豆包上的图片水印有几个特点: - 固定在右下角,尺寸 170x35px - 贴边排列,没有任何留白 - 正常手段无法禁止加载 最直接的思路就是图像处理——把水印区域用周围像素盖掉。但实际操作中发现,直接用原图的像素填充水印区域效果很差,会出现明显的纹理断裂。 后来我换了个思路:豆包在渲染列表页缩略图时,用的是无水印的高清预览图(URL 里带 image_pre_watermark),而用户点击下载时请求的才是带水印的版本(URL 里带 image_dld_watermark)。 这两个版本恰好是同一张图的两个半边可以无缝拼接。 核心原理:左右拼接 这个方案说起来很简单: 1. 拦截所有带 image_dld_watermark 的下载请求 2. 在 DOM 中找到对应的高清预览图 URL(image_pre_watermark) 3. 下载原图,取左半边(无水印) 4. 下载预览图,取右半边(无水印) 5. 拼接输出 拼接后的图片,肉眼完全看不出拼接痕迹。 

 技术实现 作为 Chrome 扩展,架构分三层: Content Script(content.js)注入到页面,负责: - 劫持 fetch 方法,拦截下载请求 - 维护请求队列,保证串行处理避免并发问题 - 从 DOM 中提取所有预览图 URL - 匹配下载图和预览图的 ID Injected Script(injected.js)注入到主世界,负责: - 监听拼接完成事件 - 通过 chrome.runtime.sendMessage 把结果发往后端 Service Worker(background.js)负责: - 调用 chrome.downloads.download() 触发下载 - 管理文件名前缀(默认 watermark_free) 用户点击下载 ↓ content.js 拦截 fetch ↓ 匹配高清预览图 URL ↓ 并发下载原图 + 预览图 ↓ Canvas 拼接左右两半 ↓ injected.js 通知 background ↓ background.js 触发系统下载 几个细节 请求队列:豆包列表页一次会加载很多图片,如果不做队列控制,多个请求并发处理会导致拼接顺序错乱。用了 Promise链式串行化处理。 图片 ID 匹配:下载图的 ID 和预览图的 ID 不完全一致,用了精确匹配 + 前缀匹配两层逻辑兜底。 去水印效果:这个方案比传统的"从原图左部像素克隆覆盖水印区域"效果好很多,因为预览图本身是完整的高清无水印图,素拼接后纹理完全对齐。 效果