[js] 写个给图片加水印的方法

haizhilin2013
2019-09-25 04:40:28 星期三
js
                    
                        
写个给图片加水印的方法
Comments per page
< Page 1 / 1 >
HCLQ 2019-09-25 01:22:43
/**
 *
 * @param {*} image 图片 img对象
 * @param {*} words 水印内容
 */
export default function(image, words) {
  const { canvas, context } = getCanvas()
  let width = image.width
  let height = image.height
  canvas.width = width
  canvas.height = height
  canvas.style.width = image.style.width
  canvas.style.height = image.style.height

  context.drawImage(image, 0, 0)

  // 重复绘制内容贴图
  const mark = getMark(words)
  for (let i = 0; i < width; i += 250) {
    for (let j = 0; j < height; j += 250) {
      context.drawImage(mark, i, j)
    }
  }
  return toImage(canvas)
}

function toImage(canvas) {
  var image = new Image()
  image.src = canvas.toDataURL('image/png')
  return image
}

// 构造内容
function getMark(content = '') {
  const { canvas, context } = getCanvas()
  canvas.width = 200
  canvas.height = 200
  context.translate(100, 100)
  context.rotate((45 * Math.PI) / 180)
  context.font = '30px 微软雅黑'
  context.textAlign = 'center'
  // 隐形水印, 肉眼不可见,图片被人下载后可用ps查看
 // content 一般是登录的信息,用以内部截图外泄后查清截图人身份用
  context.fillStyle = 'rgba(220,20,60, 0.005)' 

  const words = content.split('\n') // 以\n为换行
  const lines = words.length
  const fontHeight = context.measureText('田').width * 1.1
  const wordsHeight = fontHeight * lines
  const start = -wordsHeight / 2
  for (let i = 0; i < lines; i++) {
    context.fillText(words[i], 0, start + i * fontHeight)
  }
  return canvas
}

function getCanvas() {
  const canvas = document.createElement('canvas')
  return {
    canvas,
    context: canvas.getContext('2d')
  }
}
LinStan 2019-09-25 02:27:38

想到最简单的就是直接插入一个div通过绝对定位来实现水印显示

<body>
  <img id='a' src='.\r.jpg'>

</body>
<script>
  let imgdom = document.getElementById('a')
  let imgtop = imgdom.offsetTop;
  let imgleft = imgdom.offsetLeft;
  let styleString = 'color:white;width:300px;height:50px;display:block;position:absolute;left:' + (imgleft + 50) + 'px;top:' + (imgtop + 20) + 'px;';
  let dom = document.createElement("DIV")
  let textnode = document.createTextNode('水印');
  dom.appendChild(textnode)
  dom.style = styleString;
  document.body.appendChild(dom)
</script>
vkboo 2019-09-25 15:03:35
  • 都用Canvas的方案解决

  • 情况一:水印是图片(两张图片canvas.drawImage两次重叠即可)

<input type="file" id="uploadFile" class="clip" accept="image/*">
<label class="ui-button ui-button-primary" for="uploadFile">选择图片</label>
<img id="imgCover" src="./watermark.png" class="clip">
<p id="imgUploadX"></p>
var eleUploadFile = document.getElementById('uploadFile');
var eleImgCover = document.getElementById('imgCover');
var eleImgUploadX = document.getElementById('imgUploadX');

if (history.pushState) {
    eleUploadFile.addEventListener('change', function (event) {
        var reader = new FileReader();
        var file = event.target.files[0] || event.dataTransfer.files[0];

        reader.onload = function (e) {
            var base64 = e.target.result;
            if (base64.length > 1024 * 500) {
                alert('图片尺寸请小于500K');
                return;
            } else {
                // 使用canvas合成图片,并base64化
                imgTogether(base64, function (url) {
                    // 尺寸
                    var size = 180 / (window.devicePixelRatio || 1);
                    // 预览
                    eleImgUploadX.innerHTML = '<img src="' + url + '" width="' + size + '" height="' + size + '">';
                });
            }
        };

        reader.readAsDataURL(file);
    });

    // canvas图片合成
    var imgTogether = function (url, callback) {
        var canvas = document.createElement('canvas');
        var size = 180;
        canvas.width = size;
        canvas.height = size;

        var context = canvas.getContext('2d');

        // 这是上传图像
        var imgUpload = new Image();
        imgUpload.onload = function () {
            // 绘制
            context.drawImage(imgUpload, 0, 0, size, size, 0, 0, size, size);
            // 再次绘制
            context.drawImage(eleImgCover, 0, 0, size, size, 0, 0, size, size);
            // 回调
            callback(canvas.toDataURL('image/png'));
        };
        imgUpload.src = url;
    };
    
} else if (eleImgUploadX) {
    eleImgUploadX.className = 'remind';
    eleImgUploadX.innerHTML = '本演示IE10+下才有效果';
}
  • 情况二:水印是纯文字
#wrap {
    display: inline-block;
}
<div id="wrap">
    <img src="http://placekitten.com/600/600" id="xxx" />
</div>
<script src="js/app.js"></script>
(function () {
    // canvas 实现 watermark
    function __canvasWM({
        // 使用 ES6 的函数默认值方式设置参数的默认取值
        // 具体参见 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Default_parameters
        container = document.body,
        image,
        width = '200px',
        height = '150px',
        textAlign = 'center',
        textBaseline = 'middle',
        font = "20px microsoft yahei",
        fillStyle = 'rgba(184, 184, 184, 0.8)',
        content = '请勿外传',
        rotate = '30',
        zIndex = 1000
    } = {}) {
        var args = arguments[0];
        var canvas = document.createElement('canvas');

        canvas.setAttribute('width', image.width);
        canvas.setAttribute('height', image.height);
        var ctx = canvas.getContext("2d");

        ctx.textAlign = textAlign;
        ctx.textBaseline = textBaseline;
        ctx.font = font;
        ctx.fillStyle = fillStyle;
        ctx.rotate(Math.PI / 180 * rotate);
        ctx.fillText(content, parseFloat(image.width) / 2, parseFloat(image.height) / 2);

        var base64Url = canvas.toDataURL();
        const watermarkDiv = document.createElement("div");
        watermarkDiv.setAttribute('style', `
        position:absolute;
        top:0;
        left:0;
        width:100%;
        height:100%;
        z-index:${zIndex};
        pointer-events:none;
        background-repeat:repeat;
        background-image:url('${base64Url}')`);
        container.style.position = 'relative';
        container.insertBefore(watermarkDiv, container.firstChild);
    }

    window.__canvasWM = __canvasWM;
})();

let imgEl = document.querySelector('#xxx');

imgEl.onload = function() {
    __canvasWM({
        container: document.querySelector('#wrap'),
        image: imgEl,
        content: 'fuck'
    })
}
ZindexYG 2020-05-27 03:11:27
xiaoqiangz 2022-07-28 07:15:07

可以利用canvas来加水印,ctx.drawImage(img),最后在加上水印 ctx.fillText('水印').

排行榜
今日答题答题排行
    未答的题
    更多>
      【关注作者公众号】 以面试驱动学习--前端剑解
      【公众号推荐】 不折腾的前端和咸鱼有什么区别

      学习不打烊,充电加油只为遇到更好的自己,365天无节假日,每天早上5点纯手工发布前端知识点(死磕自己,愉悦大家)。希望大家在这浮夸的前端圈里,保持冷静,坚持每天花20分钟来学习与思考。在这千变万化,类库层出不穷的前端,建议大家不要等到找工作时,才狂刷题,提倡每日学习!欢迎大家关注3+1开源项目!希望大家每人去学习与思考!(不要为了谁而来,要为自己而努力!

      【关注官方公众号】 每天4:30-5:00推送
      【公众号推荐】 一起折腾前端算法
      【微信学习群】 备注3+1