Openlayer 切片图层添加水印

一、思路

为切片图层添加水印方法目前知道的有两种:

一种是类似超图切片服务的方式,从服务返回来的切片本身就带上了水印,如下图。但是这种方法对于普通开发来说不太现实。

另一种是等切片传回前端,在前端对切片进行二次处理,本文主要讲述如何对传回的切片进行处理。

二、流程

 首先准备一张用于做水印的透明图片,如下图,然后将图片转换为base码,方便在代码中调用。

核心方法

通过监听切片的加载回调方法

  • 获取加载完的切片,然后根据切片的尺寸,用canvas创建一个画布;

  • 将切片的src对应的图片绘制到画布上,这样就获得了一个和src图片内容一样的画布;

  • 将预先准备好的水印图片通过平铺的方法叠加到画布上,然后将画布输出为图片,这样就可以获取到叠加水印的图片;

  • 最后用处理完的输出的图片替换掉原来的切片图片,就可以得到添加水印的效果;
                var img = new Image();
                img.src = "data:image/png;your img"
                var source2 = new ol.source.ImageArcGISRest({
                    crossOrigin: "anonymous", // 需要开启才能对切片进行操作
                    url: "your url",
                })
                source2.on("imageloadend", function (evt) {
                    // var image = evt.tile.getImage();
                    var image = evt.image.getImage(); // 获取切片
                    canvas = document.createElement('CANVAS'); // 创建画布
                    canvas.width = image.width;
                    canvas.height = image.height;
                    canvas.style.width = image.width + 'px';
                    canvas.style.height = image.height + 'px'; // 根据切片大小设置画布尺寸
                    var ctx = canvas.getContext("2d");
                    ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height); // 将切片图片绘制到画布上
                    ctx.rect(0, 0, image.width, image.height);
                    ctx.fillStyle = ctx.createPattern(img, "repeat");  // 平铺预先准备好的水印
                    ctx.fill();
                    image.src = canvas.toDataURL("image/png"); // 将添加完水印的图片绑定到切片上
                });

图层加载方法

以arcgis服务为例,可以是以Tile方法进行tile切片加载,也可以用Image直接加载图片

上面的核心代码示例中是用Image的方法进行处理,用image方法进行加载,后台服务会直接返回与当前界面尺寸接近的图片

直接对整张图片进行操作也可以达到添加水印的效果,但是这样会出现一个问题,每次缓存中的图片不足以提供view的视界,就会对服务进行请求,而请求回来的又是一张接近的图片,再对水印进行操作的话,水印就会又从新的图片的左上角进行计算平铺,这样就会导致水印的位置永远都是相对于屏幕不变,而不是跟随切片进行移动。

替换成空白图层的话这种效果就会很明显,即只要获取了新的切片,水印就会刷新回最初的位置,和屏幕的相对位置一致。也就是说,只要界面刷新了图片,图层水印就会回到下图所示的位置。

上面这种效果显然不是水印图层想要的效果,所有推荐使用 tile 切片的方式进行加载

                var source2 = new ol.source.TileArcGISRest({
                    crossOrigin: "anonymous",
                    url: "your url",
                })
                source2.on("tileloadend", function (evt) {
                // source2.on("imageloadend", function (evt) {
                    var image = evt.tile.getImage(); // 获取切片
                    // var image = evt.image.getImage(); // 获取切片
                    canvas = document.createElement('CANVAS'); // 创建画布
                    canvas.width = image.width;
                    canvas.height = image.height;
                    canvas.style.width = image.width + 'px';
                    canvas.style.height = image.height + 'px'; // 根据切片大小设置画布尺寸
                    var ctx = canvas.getContext("2d");
                    ctx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height); // 将切片图片绘制到画布上
                    ctx.rect(0, 0, image.width, image.height);
                    ctx.fillStyle = ctx.createPattern(img, "repeat");  // 平铺预先准备好的水印
                    ctx.fill();
                    image.src = canvas.toDataURL("image/png"); // 将添加完水印的图片绑定到切片上
                });

通过tile方法加载得到的切片是大小一致的切片,如果视界发升变动,需要刷新底图,只需要对视界变动位置的切片进行请求,再对新的切片进行操作就可以了。

并且水印操作是对每个切片进行操作的,所以水印的相对位置始终绑定切片,因此不会出现水印回刷的情况。

投影影响

上面的例子是建立在view的投影与layer的投影一致的情况下的,如果view的投影与layer的投影不一致,在回调事件中对图片进行处理的话,会导致图片产生割裂效果

此处推测应该是切片加载完还要进行进一步处理,所以导致图片缺失。可以通过发布一个新的与view的投影一致的空图层来跳过这个问题,对空图层进行监听,设置空图层的显隐效果,同时可以实现多个图层共用一个水印图层的效果,避免对每个图层进行操作,消耗过多的性能。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值