You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何计算水印旋转角度,使其按比例适配底图对角线并最大化显示?

解决对角线水印最大化的问题

要实现水印沿图片对角线放置且保持最大比例,核心是计算正确的旋转角度,并根据旋转后的水印包围盒尺寸计算合适的缩放比例——而不是直接将旋转后的水印缩放到原图尺寸(这会导致水印内容被不必要地缩小)。

核心逻辑说明

  1. 提取尺寸:获取原图和水印的宽高参数。
  2. 计算对角线角度:通过原图的宽高比,用反正切函数计算出对角线的旋转角度(转换为度数)。
  3. 计算旋转后水印的包围盒:当水印旋转指定角度后,其外接矩形的宽高可以通过三角函数推导得出。
  4. 计算缩放比例:取原图与旋转后水印包围盒的宽、高比例中的较小值,确保水印缩放后刚好能放入原图且不超出边界。
  5. 合成水印:将缩放后的水印旋转到目标角度,再居中合成到原图上。

修改后的完整Bash脚本

#!/bin/bash

# 用户可选择模式:horizontal, vertical, diagonal, 或自定义角度(如45)
MODE="diagonal"

for pic in *
do
    # 跳过水印文件本身,避免循环处理
    if [ "$pic" = "wm.png" ]; then
        continue
    fi

    # 移除图片周围透明区域并获取原图尺寸(格式:WxH)
    size_ui=$(convert -density 300 "$pic" -page a4 -bordercolor none -border 1x1 -trim +repage jpg:- | identify -format "%wx%h" -)
    W=${size_ui%x*}
    H=${size_ui#*x}

    # 获取水印尺寸(格式:wxh)
    size_wm=$(identify -format "%wx%h" "wm.png")
    w=${size_wm%x*}
    h=${size_wm#*x}

    # 根据选择的模式计算旋转角度
    case $MODE in
        horizontal)
            degree=0
            ;;
        vertical)
            degree=90
            ;;
        diagonal)
            # 计算原图对角线角度(左上到右下方向),转换为度数
            theta=$(echo "scale=10; a=atan2($H, $W); a*180/3.1415926535" | bc -l)
            degree=$theta
            ;;
        *)
            # 验证自定义角度是否为有效数字
            if [[ $MODE =~ ^[0-9]+(\.[0-9]+)?$ ]]; then
                degree=$MODE
            else
                echo "Error: Invalid mode or angle. Use 'horizontal', 'vertical', 'diagonal', or a numeric angle."
                exit 1
            fi
            ;;
    esac

    # 将角度转换为弧度,用于三角函数计算
    rad_degree=$(echo "scale=10; $degree*3.1415926535/180" | bc -l)
    cos_theta=$(echo "scale=10; c($rad_degree)" | bc -l)
    sin_theta=$(echo "scale=10; s($rad_degree)" | bc -l)

    # 计算水印旋转后的外接矩形宽高
    wm_rot_w=$(echo "scale=10; $w*$cos_theta + $h*$sin_theta" | bc -l)
    wm_rot_h=$(echo "scale=10; $w*$sin_theta + $h*$cos_theta" | bc -l)

    # 计算缩放比例(取宽高比例的较小值,确保水印能完整放入原图)
    scale_w=$(echo "scale=10; $W / $wm_rot_w" | bc -l)
    scale_h=$(echo "scale=10; $H / $wm_rot_h" | bc -l)
    scale=$(echo "if ($scale_w < $scale_h) $scale_w else $scale_h" | bc -l)

    # 计算缩放后的水印尺寸(四舍五入为整数,符合ImageMagick的尺寸要求)
    scaled_w=$(echo "scale=0; $w*$scale + 0.5" | bc)
    scaled_h=$(echo "scale=0; $h*$scale + 0.5" | bc)

    # 执行水印合成:缩放水印 → 旋转 → 居中叠加到原图
    convert -density 300 "$pic" -page a4 \
        \( "wm.png" -background none -resize "${scaled_w}x${scaled_h}" -rotate "$degree" -gravity center \) \
        -compose over -composite "${pic%%.*}_watermarked.jpg"

done

关键点解释

  • 跳过水印文件:避免脚本循环处理水印图片本身,造成不必要的重复操作。
  • 高精度角度计算:使用bc工具进行三角函数运算,保证角度计算的准确性。
  • 包围盒推导:旋转后的水印外接矩形尺寸是决定缩放比例的核心,确保水印能以最大比例适配原图。
  • 缩放比例控制:取宽高比例的最小值,无论原图和水印的尺寸比例如何,都能保证水印完整放入原图且不超出边界。
  • 合成顺序优化:先缩放水印再旋转,比先旋转再缩放更高效,能减少不必要的像素损失。

自定义角度说明

如果需要使用自定义角度,只需将MODE变量设置为具体的角度值(如MODE="45"),脚本会自动计算对应的缩放比例,确保水印最大化适配原图。

内容的提问来源于stack exchange,提问作者AFoeee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:15:09