Gemini 无损去水印神器:基于数学算法的纯前端解决方案

Gemini 无损去水印神器:基于数学算法的纯前端解决方案

🎯 Gemini 无损去水印神器:基于数学算法的纯前端解决方案

🔗 项目地址:gemini-watermark-remover
🌐 在线体验:banana.ovo.re
⭐ 如果觉得有用,请给项目点个 Star!

📖 引言

随着 Google Gemini AI 图像生成功能的普及,越来越多的用户开始使用它来创作各种精美的图片。然而,Gemini 生成的图片右下角都会带有一个半透明的水印 Logo,这在某些场景下可能会影响图片的使用效果。

今天给大家推荐一个开源项目 gemini-watermark-remover,它能够完美无损地移除 Gemini 图片上的可见水印,而且完全在浏览器端运行,无需上传图片到服务器,充分保护用户隐私!


✨ 核心特性

🔒 100% 客户端处理,隐私至上

  • 无需后端服务器:所有图片处理都在浏览器本地完成
  • 零数据上传:图片永远不会离开你的设备
  • 即开即用:打开网页即可使用,无需注册登录

🎯 数学精确,非 AI 模型

  • 基于反向 Alpha 混合算法(Reverse Alpha Blending)
  • 不依赖 AI 模型的"幻觉"式修复
  • 数学公式保证结果的像素级精确
  • 真正的"无损"去水印

🚀 智能检测,自动适配

  • 自动识别 48×48 或 96×96 两种水印尺寸
  • 根据图片尺寸智能选择处理策略
  • 支持各种分辨率的 Gemini 生成图片

🎨 简洁易用,体验流畅

  • 拖拽上传或点击选择
  • 实时处理,秒级完成
  • 一键下载处理后的图片
  • 支持多语言界面(中文/英文)

🌐 跨平台兼容

  • ✅ Chrome 90+
  • ✅ Firefox 88+
  • ✅ Safari 14+
  • ✅ Edge 90+

🔬 技术原理深度解析

Gemini 的水印添加方式

Gemini 使用标准的 Alpha 混合(Alpha Compositing)技术来添加水印:

watermarked = α × logo + (1 - α) × original 

其中:

  • watermarked:带水印的像素值
  • α:Alpha 通道值(0.0-1.0,控制透明度)
  • logo:水印 Logo 的颜色值(白色 = 255)
  • original:原始像素值(我们要恢复的目标)

反向求解算法

既然知道了 Gemini 添加水印的公式,我们就可以通过数学逆运算来恢复原始图像:

original = (watermarked - α × logo) / (1 - α) 

关键步骤:

  1. 捕获 Alpha 通道:在纯色背景上提取水印,重建 Alpha 映射表
  2. 应用逆公式:对每个像素应用反向混合公式
  3. 边界处理:限制 Alpha 值范围,避免除零错误
  4. 像素裁剪:确保结果在 [0, 255] 范围内

水印检测规则

项目实现了智能的水印检测机制:

图像尺寸条件水印尺寸右边距下边距
宽 > 1024 高 > 102496×9664px64px
其他情况48×4832px32px

💻 核心代码实现

1. Alpha Map 计算

/** * 从背景捕获图像计算 Alpha 通道 */exportfunctioncalculateAlphaMap(bgCaptureImageData){const{ width, height, data }= bgCaptureImageData;const alphaMap =newFloat32Array(width * height);// 对每个像素,取 RGB 三通道最大值并归一化到 [0, 1]for(let i =0; i < alphaMap.length; i++){const idx = i *4;// RGBA 格式,每像素 4 字节const r = data[idx];const g = data[idx +1];const b = data[idx +2];// 取三通道最大值作为亮度值const maxChannel = Math.max(r, g, b);// 归一化到 [0, 1] 范围 alphaMap[i]= maxChannel /255.0;}return alphaMap;}

2. 反向 Alpha 混合

/** * 使用反向 Alpha 混合移除水印 */exportfunctionremoveWatermark(imageData, alphaMap, position){const{ x, y, width, height }= position;constALPHA_THRESHOLD=0.002;// 忽略极小 alpha 值(噪声)constMAX_ALPHA=0.99;// 避免除以接近零的值constLOGO_VALUE=255;// 白色水印的颜色值// 处理水印区域的每个像素for(let row =0; row < height; row++){for(let col =0; col < width; col++){// 计算在原图中的索引const imgIdx =((y + row)* imageData.width +(x + col))*4;const alphaIdx = row * width + col;let alpha = alphaMap[alphaIdx];// 跳过极小 alpha 值if(alpha <ALPHA_THRESHOLD)continue;// 限制 alpha 值避免除零 alpha = Math.min(alpha,MAX_ALPHA);const oneMinusAlpha =1.0- alpha;// 对每个 RGB 通道应用反向混合for(let c =0; c <3; c++){const watermarked = imageData.data[imgIdx + c];// 反向 alpha 混合公式const original =(watermarked - alpha *LOGO_VALUE)/ oneMinusAlpha;// 裁剪到 [0, 255] 范围 imageData.data[imgIdx + c]= Math.max(0, Math.min(255, Math.round(original)));}}}}

3. 主引擎协调

/** * 水印引擎类 - 协调整个处理流程 */exportclassWatermarkEngine{asyncremoveWatermarkFromImage(image){// 1. 创建 Canvas 处理图像const canvas = document.createElement('canvas'); canvas.width = image.width; canvas.height = image.height;const ctx = canvas.getContext('2d'); ctx.drawImage(image,0,0);// 2. 获取图像数据const imageData = ctx.getImageData(0,0, canvas.width, canvas.height);// 3. 检测水印配置const config =detectWatermarkConfig(canvas.width, canvas.height);const position =calculateWatermarkPosition(canvas.width, canvas.height, config);// 4. 获取对应尺寸的 alpha mapconst alphaMap =awaitthis.getAlphaMap(config.logoSize);// 5. 移除水印removeWatermark(imageData, alphaMap, position);// 6. 写回 Canvas ctx.putImageData(imageData,0,0);return canvas;}}

🎬 效果展示

无损对比图

下图展示了原图与去水印后的像素级差异对比,可以看到除了水印区域外,其他部分完全一致

无损 diff 示例

实际案例

原图(带水印)处理后(无水印)
示例1
在这里插入图片描述
处理后1
在这里插入图片描述

🚀 使用方法

方式一:在线网站(推荐)

  1. 打开 banana.ovo.re
  2. 拖拽或点击选择带水印的 Gemini 图片
  3. 等待自动处理(通常只需 1-2 秒)
  4. 点击下载按钮保存处理后的图片

方式二:油猴脚本(进阶)

如果你经常使用 Gemini,可以安装油猴脚本实现自动去水印

  1. 安装 TampermonkeyGreasemonkey
  2. 打开脚本地址:gemini-watermark-remover.user.js
  3. 点击安装
  4. 在 Gemini 对话页面,点击"复制图片"或"下载图片"时会自动去除水印

方式三:本地部署

# 克隆项目git clone https://github.com/journey-ad/gemini-watermark-remover.git cd gemini-watermark-remover # 安装依赖pnpminstall# 开发模式pnpm dev # 生产构建pnpm build # 本地预览pnpm serve 

📁 项目结构

gemini-watermark-remover/ ├── public/ │ ├── index.html # 主页面 │ └── terms.html # 使用条款 ├── src/ │ ├── core/ # 核心算法模块 │ │ ├── alphaMap.js # Alpha 通道计算 │ │ ├── blendModes.js # 反向混合算法 │ │ └── watermarkEngine.js # 主引擎协调器 │ ├── assets/ # 预捕获的水印资源 │ │ ├── bg_48.png # 48×48 水印 Alpha 图 │ │ └── bg_96.png # 96×96 水印 Alpha 图 │ ├── i18n/ # 国际化语言文件 │ ├── userscript/ # 油猴脚本 │ ├── app.js # 网站应用入口 │ └── i18n.js # 国际化工具 ├── docs/ # 示例图片 ├── dist/ # 构建输出 └── build.js # 构建脚本 

🎓 技术亮点总结

1. 数学严谨性

  • 基于标准的 Alpha 混合公式
  • 通过逆运算精确恢复原始像素
  • 避免了 AI 模型的不确定性

2. 性能优化

  • 使用 Float32ArrayUint8ClampedArray 提升计算效率
  • Alpha Map 缓存机制减少重复计算
  • Canvas API 硬件加速

3. 边界处理

  • ALPHA_THRESHOLD:过滤噪声
  • MAX_ALPHA:避免除零错误
  • 像素值裁剪:确保结果合法

4. 工程化实践

  • ES6 模块化设计
  • 清晰的代码注释
  • 完善的错误处理
  • 国际化支持

⚠️ 重要说明

局限性

  1. 仅移除可见水印:只能去除右下角的半透明 Logo
  2. 无法处理隐形水印:不能去除 SynthID 等隐写水印
  3. 版本依赖:针对 Gemini 当前(2025年)的水印模式设计

免责声明

⚠️ 本工具仅供个人学习研究使用

移除水印可能涉及法律问题,请确保你的使用行为符合:当地法律法规Gemini 服务条款知识产权相关规定

作者不鼓励将本工具用于侵权、虚假陈述或其他非法用途。

本软件按"原样"提供,不提供任何形式的保证。

🌟 为什么推荐这个项目?

1. 技术价值

  • 展示了如何用纯数学方法解决实际问题
  • 代码简洁优雅,适合学习 Canvas API 和图像处理
  • 完整的工程化实践案例

2. 实用价值

  • 真正解决了 Gemini 用户的痛点
  • 完全免费开源
  • 隐私保护做得很好

3. 学习价值

  • 理解 Alpha 混合原理
  • 学习浏览器端图像处理
  • 掌握 TypedArray 的使用

🔗 相关资源


🎉 总结

gemini-watermark-remover 是一个技术上严谨、实用性强、隐私保护到位的开源项目。它用优雅的数学方法解决了 Gemini 图片水印问题,代码质量高,值得学习和使用。

如果你:

  • 经常使用 Gemini 生成图片
  • 对图像处理算法感兴趣
  • 想学习浏览器端的高性能计算
  • 关注用户隐私保护

那么这个项目绝对值得你关注!

别忘了给项目点个 ⭐ Star,支持开源!


📮 互动交流

欢迎在评论区分享:

  • 你使用这个工具的体验
  • 对算法原理的理解和疑问
  • 其他有趣的图像处理技巧

让我们一起学习进步!💪


Read more

C++: 实现贝尔曼-福特算法以查找最短距离 从给定节点到有向图中的所有其他节点,其 边已被指定为实值长度(附带源码)

项目背景详细介绍 在图论与算法设计中,最短路径问题是最基础、也是最重要的问题之一。给定一个带权图以及一个起始节点,我们希望计算: 从给定起点到图中所有其他节点的最短距离。 在很多经典教材和工程实践中,大家最熟悉的可能是 Dijkstra 算法。然而,Dijkstra 算法有一个非常重要的限制: * 边权必须是非负的 一旦图中存在负权边(例如在金融套利、能量模型、约束优化等问题中),Dijkstra 将不再适用。 此时,**贝尔曼-福特算法(Bellman–Ford Algorithm)**就成为了标准选择。 贝尔曼-福特算法具有以下显著特点: * 支持 实值边权(包括负数) * 能够检测 负权环(Negative Cycle) * 算法原理清晰,非常适合教学与理论推导 在工程实践中,它被广泛应用于: * 网络路由协议(如 RIP) * 含约束条件的最短路径问题 * 金融中的套利检测 * 编译器中的依赖分析 本项目将以教学 + 工程实现为目标,使用 C++,完整实现:

By Ne0inhk
进阶数据结构: AVL树

进阶数据结构: AVL树

嘿,各位技术潮人!好久不见甚是想念。生活就像一场奇妙冒险,而编程就是那把超酷的万能钥匙。此刻,阳光洒在键盘上,灵感在指尖跳跃,让我们抛开一切束缚,给平淡日子加点料,注入满满的passion。准备好和我一起冲进代码的奇幻宇宙了吗?Let's go! 我的博客:yuanManGan 我的专栏:C++入门小馆 C言雅韵集 数据结构漫游记  闲言碎语小记坊 题山采玉 领略算法真谛 目录 AVL相关概念:  AVL树的结构 Insert  旋转 右旋: 编辑 左单旋:  右左双旋: 左右双旋:  完整的插入: 其他简单的操作:  测试: AVL相关概念: AVL树是由二叉搜索树加上一定的限制而形成的树,AVL树:它的左右子树都是AVL树,且左右子树的高度差的绝对值不超过1。AVL树是⼀颗⾼度平衡搜索⼆叉树, 通过控制⾼度差去控制平衡。

By Ne0inhk
【算法详解】理解KMP,真的那么难吗?—— 一篇讲透它的核心思想

【算法详解】理解KMP,真的那么难吗?—— 一篇讲透它的核心思想

🫧 励志不掉头发的内向程序员:个人主页  ✨️ 个人专栏: 《C++语言》《Linux学习》 🌅偶尔悲伤,偶尔被幸福所完善 👓️博主简介: 文章目录 * 前言 * 一、相关概念 * 二、前缀函数 * 三、计算前缀函数 * 四、用前缀函数解决字符串匹配 * 五、kmp 算法模板 * 六、next 数组版本 * 七、周期和循环节 * 总结 前言 本文用尽量详细的语言来讲解说明 kmp 算法内容,学习之前需要知道一点点动态规划的基础,如果不知道最好去了解了解。我们一起来看看算法吧。 一、相关概念 在学习 kmp 算法之前,我们得先提前了解最基本的 “ 动态规划 ” 的知识,否则可能学习的时候会有一些困难,因为它的原理类似于动态规划。 字符串: * 用字符构成的的序列就是字符串。 这个概念很简单,但是我们这里有个小技巧:就和动态规划那样,

By Ne0inhk
力扣校招算法通关:双指针技巧全场景拆解 —— 从数组操作到环检测的高效解题范式

力扣校招算法通关:双指针技巧全场景拆解 —— 从数组操作到环检测的高效解题范式

文章目录 * 前言 * 双指针 * 例题讲解 * 移动零 力扣 * 复写零 力扣 * 快乐数 力扣 * 盛最多水的容器 力扣 * 有效三角形的个数 力扣 * 查找总价格为目标值的两个商品 力扣 * 三数之和 力扣 前言 在力扣校招算法题中,双指针技巧是一类高频且实用的解题方法。它并非真正的 “指针”,而是通过两个数组下标(或迭代器)的协同移动,在数组划分、区间求解、环检测等场景中实现高效遍历与逻辑处理,往往能将时间复杂度从暴力法的 O(n平方)优化至O(n),是校招笔试和面试中突破数组类难题的关键武器。 本专栏将围绕力扣校招高频的双指针题型展开,从 “移动零”“复写零” 的数组操作,到 “快乐数” 的环检测、“盛最多水的容器” 的区间优化,再到 “三数之和” 的多指针协同,逐一拆解双指针的核心逻辑、边界处理与去重技巧,

By Ne0inhk