图片加水印

文字或图片水印平铺/角落两种排布,导出 PNG、JPEG 或 WebP。

这一页把文字或图片水印合成进底图的像素,再导出 PNG、JPEG 或 WebP。排布两种:九宫格单点与旋转平铺;底图可以多张进同一个列表,批量走同一套设置。底图和水印图都只从文件选择、拖放或粘贴进入,解码、合成、编码全在浏览器内存里。EXIF 方向优先交给 createImageBitmap(file, {imageOrientation:"from-image"}),这个值按 EXIF 摆放且是规范默认;该 API 不可用时回退 HTMLImageElement,此时方向是否被应用取决于浏览器版本,页面会把走的是哪条路如实写出来。

本页代码没有 fetch、XHR 与 sendBeacon,也不接收图片 URL(那等于替你把一次请求发到站外),同样不加载任何 web 字体,字体栏只给本机通用字族。烧进像素的水印不是防篡改——它可以被裁掉、被盖住、被重新压缩,也能被修复类工具抹掉;挂在 DOM 上的 CSS 遮罩更是零防护,开发者工具删掉那个节点就没了。这一页只帮你做署名和提高顺手搬运的成本,不承诺防盗。「质量」那一栏只进 JPEG 与 WebP 这两条有损编码,PNG 是无损的、toBlob 根本不读这个数;JPEG 没有透明通道,底图带 alpha 时会按你给的底色铺底合成并明说透明区不再是透明的;WebP 能不能编不是看名字而是实测,编不出来就自动退回 PNG 并写在提示里。「下载全部」逐个触发 <a download>,是 N 个独立文件、不是压缩包,本页不引入 JSZip。

图片加水印怎么用

  • 排布选哪种,收起不等于关掉:盖全图用平铺:默认 −30°、横向间距 60、纵向 46,格数与点位实时算给你看;署位置用九宫格:默认右下、边距 4%,再配 X/Y 偏移微调。图片水印按底图宽度的百分比缩放(默认 18%,可设到 200%,超过 100% 就是水印比底图还宽、会被裁掉一部分),它带 alpha 才有意义——拿 JPEG 当水印图会拖着一块不透明的底。参数轨那五组(文字 / 图片 / 平铺 / 位置 / 导出)是原生 `<details>`,标题上那行小字就是当前生效值,例如「字号 6%(未换算) · 颜色 #ffffff · 不透明 0.35 · 旋转 -30° · 阴影」;收起只是把控件藏起来,值仍在 DOM 里照常参与读取与合成,想专心调一处就把别处收掉,参数不会丢。真正让某一组消失的是水印类型和平铺开关:切到「图片水印」才出现「图片」组,切回文字它就不在页面上;「平铺满整张」开着时「位置」组整组不显示(平铺不走单点摆放,摘要里会补一句「平铺中不生效」),关掉平铺才出现九宫格,反过来三个间距控件就被藏起来。真正让某一组消失的是水印类型和平铺开关:切到「图片水印」才出现「图片」组,切回文字它就不在页面上;「平铺满整张」开着时「位置」组整组不显示(平铺不走单点摆放,摘要里会补一句「平铺中不生效」),关掉平铺才出现九宫格,反过来三个间距控件就被藏起来。页面上是四块:左上「实时预览」(固定高度的棋盘底容器,canvas 的像素尺寸按容器实测来定),预览下方并排两个拖放格(底图可多张、水印图单张),右侧一条 288px 的「参数」细轨(文字 / 图片 / 平铺 / 位置 / 导出五组原生折叠,标题上直接写当前生效值),下面是「批量结果(体积对比 + 逐个下载)」。参数改动走 140ms 防抖重合成,分段按钮与开关是点击即时;预览固定在左上主位,参数轨粘在视口上、自身比视口高时自己滚,窄屏(≤900px)塌成单列并把预览降到参数轨下面。
  • 看读数而不是凭感觉:预览格标题写「底图 W×H → 导出 W×H」;画布下方那行写预览实际显示的像素与百分比(100% 时注明「1:1 显示」,否则写「仅缩放显示」)、后面跟着「实际导出 …(与屏幕 dpr 无关)」、字号换算结果与摆放方式(平铺写次数与格数,单点写锚点与边距)。发生过钳取或回退就写在预览正下方那条提示里:EXIF 走的是哪条解码路、底图带 alpha、最大边缩了尺寸、质量越界——没有就不占地方。「平铺覆盖数学」那一格标题上是「W×H · 0° N 格 · 45° M 格」,展开能看两种角度各自的行列与点位怎么算出来的。底图体检在拖放格下面逐张列文件头识别出的格式、像素与百万像素数、有没有透明通道,以及 0 字节、解不出尺寸、1×1、多帧动画各自的提醒;图片水印那一行还会按你刚改的百分比算出约多少像素宽。混合模式下拉下面那一行实时写出当前模式的说文。「质量」那一栏要过钳位:小于等于 0 或不是数字都按 0.82、超过 1 按 1,而这次钳取会写在预览正下方那条提示里,不静默改你的数;WebP 能不能编不是看名字而是实测——blob 的 MIME 与字节头都得出 RIFF 加 WEBP 才算成功。
  • 批量与像素预算:预览下方的工具条有「按设置处理全部」与「只处理当前这张」两颗按钮,右侧那行写进度:处理中是「N/M(另有 X 张解不出像素,不参与)」,跑完是「已完成 N/M」,失败数既进括号也写进对应那一行。一次批处理受总像素上限约束(默认 40MP,设 0 表示不设闸),超了整批拦下、在错误横幅里逐张列出尺寸,并给出减张数与调小最大边两条出路,而不是让标签页转到假死。结果表可逐张下载,「下载全部(逐个文件,非压缩包)」是 N 个独立文件;下载用的对象 URL 一律延后回收,避免同步释放把还没取到文件的下载静默取消。结果表逐张列「尺寸、原字节 → 新字节(百分比)、水印次数」,导出反而变大时那一行标 ⚠,文件名是原名加 -wm 后缀再把扩展名换成导出格式,路径分隔符那一类字符会被换成下划线;表头右侧的汇总三种状态分开写——有结果时「N 张 · 合计 X」,单张失败再加「· M 张失败」,WebP 退回时补一句,被像素预算拦下时写「上次处理没成功」,还没跑过时写「还没有结果」并在表体留一行原因。
  • 边距与偏移怎么算:位置的数学都是显式算的。九宫格单点是左上、上中、右上、左中、正中、右中、左下、下中、右下,外加 X/Y 偏移。边距按「底图该轴的百分比」计,横竖各用各的边长:1000×400 的底图设 5%,就是横向离边 50px、纵向离边 20px,而不是按短边统一取一个像素值;边距夹在 0 到 50%,偏移量在夹取之后叠加,正中锚点本来就是居中,边距对它不起作用;水印比底图大或偏移过头时给的是越界标记和提示,不是静默裁掉。
  • 字号与平铺的覆盖数学:字号可以按绝对像素给(下限 1px、上限 2000px),也可以按百分比给,百分比要选参照边——底图宽、底图高、短边或对角线,结果封顶在参照边长度、最低 1px;超长文本按每行上限硬折行而不缩字号,因为被压到十几个像素的水印在导出图里等于消失。平铺的覆盖范围按旋转后的外接矩形算:涂 θ 角时要在自己的坐标系里盖住宽 |cosθ|·W + |sinθ|·H、高 |sinθ|·W + |cosθ|·H 的矩形,格数向上取整。只按底图宽高铺格子是这个功能最经典的做法错误——底图四角旋到水印坐标系后正好落在这个外接矩形的边界上,朴素网格到不了。1000×400 的底图配 160×64 的图块加 40px 间距,45° 需要 5×10 共 50 个点位,而朴素算法只给 5×4 共 20 个,四个角会露白;页面把两个数都算出来并列,角度为 0 时两者相等。间距小于等于 0、步长非法或不是数字都会被夹到下限,并标出这次发生过夹取。

常见问题

加了水印就能防止图片被搬走吗?

不能,这一页不作这个承诺。像素里烧进去的标记可以被裁边、被覆盖、被二次压缩,也能被修复类工具抹掉;靠边的位置最容易被直接裁掉,平铺比单点麻烦一些,但同样只是提高成本。CSS 或 DOM 遮罩是另一回事:它根本没改图片数据,右键另存拿到的是干净原图,开发者工具删掉那个节点也就删掉了「水印」。本页能做的是把标记按你要的位置、浓淡和混合方式稳定地合成进像素,并如实告诉你它是署名手段而不是防护手段。

在高分屏上看着清楚,导出的会不一样吗?

不会因屏幕而变。导出尺寸只吃底图自己的宽高和可选的「最大边」上限,devicePixelRatio 传进这条算式也不参与运算,所以高分屏不会让文件多出一个像素,普通屏也不会少。预览是 CSS 缩放过的,看着比实际大或小都正常。真要控制体积与清晰度就显式设最大边:它按长边等比缩放,水印字号和平铺步长同比例缩小,位置不会偏。

GIF 动图加水印后还剩几帧?

只剩第一帧。Canvas 取的是解码器给的首帧,所以本页在体检时先数 GIF 图形控制扩展 0x21 0xF9 的出现次数、再看 WebP 的 VP8X 头里 ANIM 标志位(flags 的 0x02)是否为 1,命中就把「动图只取第一帧」写在提示条里,导出的会是静态图。识别范围只有这两种容器:APNG 的 acTL 块不在嗅探之列,它同样只取首帧但不会得到警告。要保留动画得在图层或视频层面另想办法,这一页不假装能做。

混合模式可以选哪些?写了别的名字会怎样?

混合模式只认列表里那 11 个名字:source-over、multiply、screen、overlay、darken、lighten、difference、exclusion、lighter、destination-out、copy,选中哪个就把它的语义按 MDN 的 globalCompositeOperation 文档写在下拉下方那一行里,列表之外的字符串会被白名单挡下、画布退回默认叠放。

半透明水印的浓度是按什么算的?

像素层面的合成不走「源色加底色乘一减 alpha」那种预乘捷径,而是按 W3C 绘图规范的非预乘式 Co=(1−αb)·Cs+(1−αs)·Cb+αs·αb·B(Cb,Cs) 再除以 αo;区别在半透明水印上是实打实的,预乘式会把水印画得比设定值浓,alpha 为 0 的水印甚至还会改色,而这里 alpha 为 0 就真的不改色。

对应功能编号 #146无需安装,手机端同样可用按 Ctrl + K 换工具