视频截图时如何让水印始终显示在图片右下角?

IT人子诺 阅读 4

在用HTML5视频标签做截图功能时,想给截图添加固定位置的水印,但发现水印位置总不对。我尝试在canvas上先画视频帧再叠加水印图片,但缩放后水印要么偏移要么覆盖主要内容:


<video id="myVideo" width="640" height="360"></video>
<canvas id="canvas"></canvas>
<img id="watermark" src="logo.png" style="display:none">

JS代码里这样绘制:


const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, 640, 360);
ctx.drawImage(watermark, 500, 300); // 这里的坐标怎么算才不会变形时错位?

当视频宽高比变化时,水印就跑到画面外面了,有什么计算坐标的方法能保证水印始终在截图的右下角?

我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
瑞芹(打工版)
这个问题我也踩过坑,说白了就是坐标计算没搞对。你现在的写法是直接写死了水印的坐标,比如 ctx.drawImage(watermark, 500, 300),这种方式在视频宽高比或者尺寸变化时肯定会出问题。

要让水印始终显示在右下角,核心思路是动态计算水印的位置,而不是用固定值。具体来说,你需要根据当前画布的宽度和高度,减去水印图片的宽度和高度,再加上一点边距,这样就能保证水印始终在右下角。

下面是一个改好的代码示例:


const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const watermark = document.getElementById('watermark');

// 假设视频和画布尺寸一致
const videoWidth = 640;
const videoHeight = 360;

// 设置画布尺寸
canvas.width = videoWidth;
canvas.height = videoHeight;

// 绘制视频帧
ctx.drawImage(video, 0, 0, videoWidth, videoHeight);

// 动态计算水印位置
const margin = 10; // 水印距离边缘的边距
const watermarkX = videoWidth - watermark.width - margin;
const watermarkY = videoHeight - watermark.height - margin;

// 绘制水印
ctx.drawImage(watermark, watermarkX, watermarkY, watermark.width, watermark.height);


关键点在于 watermarkXwatermarkY 的计算。我们用画布的宽度减去水印的宽度,再减去一个边距,就得到了水印的正确起始位置。高度同理。

如果你的视频宽高比会动态变化,记得在每次绘制之前重新获取视频的实际宽高,并同步更新画布的尺寸,否则还是会错位。另外,别忘了确保水印图片已经加载完成,否则 watermark.widthwatermark.height 可能是 0,导致计算出错。

踩过这个坑之后,我的建议是尽量封装一个通用的函数来处理这种需求,避免每次都手动算坐标。别走弯路,省得调试到怀疑人生。
点赞
2026-02-19 01:05
夏侯晓莉
要让水印始终显示在截图的右下角,关键是动态计算水印的位置,而不是写死坐标。常见的解决方案是根据canvas的实际宽高和水印图片的尺寸来调整位置。

先获取canvas的宽度和高度,再减去水印的宽度和高度,再加上一点边距,这样就能保证水印固定在右下角。代码可以这么写:


const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const watermark = document.getElementById('watermark');

// 假设canvas已经设置好宽高
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;

// 水印图片加载完成后绘制
watermark.onload = function() {
// 绘制视频帧
ctx.drawImage(video, 0, 0, canvasWidth, canvasHeight);

// 计算水印位置
const margin = 10; // 边距
const watermarkX = canvasWidth - watermark.width - margin;
const watermarkY = canvasHeight - watermark.height - margin;

// 绘制水印
ctx.drawImage(watermark, watermarkX, watermarkY, watermark.width, watermark.height);
};


这里有几个关键点:
1. 要等水印图片加载完成后再绘制,否则可能拿不到宽高。
2. 动态计算水印的x和y坐标,用canvas的宽高减去水印的宽高,再加上一个固定的边距。
3. 如果canvas的宽高会变化,记得每次绘制前重新获取canvas的宽高。

如果视频的比例会发生变化,比如用户可以切换横屏竖屏,那就需要监听resize事件或者在每次绘制时重新调整canvas的尺寸,同时重新计算水印位置。

有时候水印图片太大也会导致问题,建议提前调整水印图片的尺寸,或者在绘制时按比例缩放。总之核心就是动态计算,别写死坐标就对了。
点赞 1
2026-02-18 13:04