搜索全站
建站 12 分钟阅读

图片站水印与版权保护方案:自动水印与右键限制的真实效果

加水印和禁右键到底有多大用?本文讲清 WordPress 自动水印的实现代码、右键限制为何形同虚设、真正有效的三层防护(水印、防盗链、溯源),以及版权声明与取证的正确做法。

U
UFO_PF 2021-06-11 · 阅读 12 分钟
图片 建站
阅读提示
本文约 4,782 字,预计阅读 12 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:禁了右键,图还是被搬走了

有摄影师给图片站加了”禁止右键”脚本,以为万无一失。结果一周后在某电商详情页看到了自己的图——对方用浏览器开发者工具直接从 Elements 面板复制了图片地址,或者更简单:截图。更让他无奈的是,那张图连水印都没有,因为水印只在详情页的大图上加,列表页的缩略图没有。

这件事说明两个问题:第一,禁右键是”防君子不防小人”的典型,它唯一的真实作用是增加一点点操作门槛;第二,水印必须加在”会被带走的那一版”上,而不是加在你觉得好看的那一版。图片站的版权保护不是靠某一个神奇插件,而是靠一套组合方案:可见水印做声明,隐形标记做溯源,访问控制做拦截,法律手段做兜底。

原理分析:四种保护手段的真实强度

右键/拖拽限制:纯前端,通过监听 contextmenu、dragstart 事件实现。强度几乎为零——禁用 JavaScript、用开发者工具、用截图、用手机长按都能绕过。而且它会影响正常用户(比如想”新标签页打开”的人)。

可见水印:在图片上叠加半透明的文字或图案。强度中等——无法阻止下载,但能阻止”直接使用”。裁剪和抹除需要成本,大多数盗图者会转向没有水印的图。关键是位置与密度:固定在角落的水印容易被裁掉,平铺或位于主体上的水印更难处理。

隐形水印/溯源:在下载时按用户 ID 生成不同的水印或追踪标识,泄露后可定位来源。强度较高,是维权取证的关键。

防盗链与鉴权:通过 referer 校验、签名链接控制访问。强度中等,能拦住大部分”直接引用”。

手段 阻止下载 阻止使用 可溯源 副作用
禁右键 否 否 否 影响体验
可见水印 否 部分 弱 影响观感
隐形水印 否 否 强 需额外开发
防盗链 部分 否 否 可能误拦

保姆级实操

步骤 1:上传时自动生成带水印的版本。 用 wp_generate_attachment_metadata 钩子,在缩略图生成后叠加水印,保留原图。

add_filter( 'wp_generate_attachment_metadata', 'mimangfei_add_watermark', 10, 2 );
function mimangfei_add_watermark( $metadata, $attachment_id ) {
    if ( empty( $metadata['sizes'] ) || ! wp_attachment_is_image( $attachment_id ) ) {
        return $metadata;
    }
    $file = get_attached_file( $attachment_id );
    if ( ! $file ) {
        return $metadata;
    }

    $editor = wp_get_image_editor( $file );
    if ( is_wp_error( $editor ) ) {
        return $metadata;
    }

    $size = $editor->get_size();
    $font = get_stylesheet_directory() . '/assets/fonts/SourceHanSans-Regular.otf';

    if ( file_exists( $font ) && $size['width'] > 600 ) {
        // GD 编辑器支持 GD 专属方法,先做能力探测
        if ( method_exists( $editor, 'image' ) ) {
            $im = $editor->image;
            $white = imagecolorallocatealpha( $im, 255, 255, 255, 90 );
            $font_size = max( 14, (int) ( $size['width'] / 40 ) );
            $text = '© mimangfei.com';
            $box  = imagettfbbox( $font_size, 0, $font, $text );
            $x    = (int) ( $size['width'] - ( $box[2] - $box[0] ) - 20 );
            $y    = (int) ( $size['height'] - 20 );
            imagettftext( $im, $font_size, 0, $x, $y, $white, $font, $text );
        }
    }

    $editor->save( $file );
    return $metadata;
}

步骤 2:只给大图加水印,列表图保持干净。 用尺寸判断控制作用范围,兼顾观感与保护。

function mimangfei_watermark_target_sizes( $metadata ) {
    $targets = array( 'gallery_large', 'full' );
    $result  = array();
    foreach ( $targets as $t ) {
        if ( isset( $metadata['sizes'][ $t ] ) ) {
            $result[] = $metadata['sizes'][ $t ]['file'];
        }
    }
    return $result;
}

步骤 3:配置防盗链。 拦住直接引用,但放行搜索引擎与正常来源。

location ~* \.(?:jpg|jpeg|png|webp)$ {
    valid_referers none blocked server_names
                   *.mimangfei.com
                   *.baidu.com *.google.com *.bing.com;
    if ($invalid_referer) {
        # 返回带水印的占位图,而不是硬 403
        rewrite ^ /watermarked-placeholder.jpg last;
    }
    expires 30d;
}

# 限制单 IP 请求频率,缓解批量抓取
limit_req_zone $binary_remote_addr zone=imgzone:10m rate=30r/s;
location /wp-content/uploads/ {
    limit_req zone=imgzone burst=60 nodelay;
}

步骤 4:加”防君子”的前端限制。 明确告诉自己这只是门槛,不是防护。

document.addEventListener( 'contextmenu', function ( e ) {
    if ( e.target.closest( '.gallery-masonry__item' ) ) {
        e.preventDefault();
    }
} );
document.addEventListener( 'dragstart', function ( e ) {
    if ( e.target.tagName === 'IMG' ) {
        e.preventDefault();
    }
} );

步骤 5:给下载用户生成可溯源的标识。 记录用户 ID 与时间戳,泄露后可定位。

function mimangfei_download_token( $user_id, $post_id ) {
    $payload = $user_id . '|' . $post_id . '|' . time();
    $token   = hash_hmac( 'sha256', $payload, wp_salt( 'auth' ) );
    return substr( $token, 0, 16 ) . '-' . base64_encode( $payload );
}

function mimangfei_parse_token( $token ) {
    $parts = explode( '-', $token );
    if ( 2 !== count( $parts ) ) {
        return false;
    }
    $payload = base64_decode( $parts[1], true );
    if ( ! $payload ) {
        return false;
    }
    list( $uid, $pid, $time ) = array_pad( explode( '|', $payload ), 3, 0 );
    return array(
        'user_id' => (int) $uid,
        'post_id' => (int) $pid,
        'time'    => (int) $time,
    );
}

步骤 6:版权声明与取证。 在页面放明确的版权声明,发现侵权时用可信时间戳或区块链存证平台固定证据,再发函或起诉。水印和访问日志是核心证据。

常见踩坑

  • 以为禁了右键就安全,实际开发者工具一秒破。
  • 只给详情页大图加水印,缩略图没加,被盗的恰恰是缩略图。
  • 水印固定在右下角,被裁剪掉就毫无痕迹。
  • 水印透明度太高(alpha > 100),去水印工具一键抹除。
  • 防盗链把搜索引擎也拦了,图片搜索流量全丢。
  • 案例:某图库站发现自己的图片被批量搬运到海外站点。由于当初只在详情页加了浅色水印,搬运方直接取了列表页的 800px 缩略图,画面干净可用。事后改造:所有超过 400px 的派生尺寸统一烧入半透明平铺水印,下载接口为会员生成带 ID 的隐形标记。三个月后再次发现泄露时,通过标记直接定位到了泄露账号,完成了取证。
  • 加水印时直接覆盖原图,想恢复原图时才发现没有备份。
  • 用 GD 的 imagettftext() 但字体路径写错,报 “Could not find/open font”,水印静默失败。

总结

保护是否到位,用一个问题判断:如果这张图被搬到别的站点,我能不能证明它是我的?能证明(水印 + 溯源标记 + 日志),说明方案有效;不能,说明只做了表面功夫。行动清单:① 所有对外可见尺寸统一烧入水印;② 水印平铺或压在主体上,不固定在角落;③ 防盗链放行搜索引擎与空来源;④ 下载带用户级溯源标识;⑤ 保留未加水印的原图;⑥ 侵权时先存证再交涉。图片站的存储与展示环节见 WordPress 图片素材站搭建、资源站文件存储与流量成本 与 WordPress 图片优化。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。