検索
ホームページウェブフロントエンドフロントエンドQ&Aウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析

ウォーターマークを実装するにはどうすればよいですか?この記事では、ウォーターマークを実装するいくつかの方法を紹介します。困っている友達はそれについて学ぶことができます~

ウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析

#問題が発生しました#In日常業務では、多くの機密データに遭遇することがよくありますが、データ漏洩を防ぐために、データを「パッケージ化」する必要があります。その目的は、データ漏洩に興味を持つ「犯罪分子」に厳しい「世論の圧力」の下で違法行為を断念させ、戦わずして他者を打ち負かす効果を達成する「犯罪未遂」をさせることである。セキュリティ部門で働く私たちにとって、データセキュリティの概念は長年染み付いており、あらゆる言葉や写真に漏洩のリスクがあるかどうかを常に念頭に置いておく必要があります。私たちは考えてきました。たとえば、写真の透かしは、仕事の過程でよく遭遇する問題です。私の仕事内容がレビュープラットフォームの開発であるため、レビュープラットフォームには危険な画像が掲載されることが多いのですが、レビュー担当者のセキュリティ意識にばらつきがあることを考慮すると、危険なことが起こらないように画像にウォーターマークを入れる必要があります。 。 の。

問題の分析

まず、ビジネス シナリオを考慮すると、この段階での問題は、監査プロセス中のデータ漏洩を心配することだけです。個人を特定できるテキストやその他のデータを画像に追加します。このようにして、漏洩したデータに基づいて個人を追跡することができますが、その最も重要な役割は、トラブルを事前に予防することであることは言うまでもありません。

問題の解決策

実装方法

ウォーターマークを実装するには多くの方法があり、フロントに分けられます。 -エンド ウォーターマークとバックエンド ウォーターマーク フロントエンド ウォーターマークの利点は 3 点に要約できます。第一に、サーバー リソースを占有せず、クライアントの計算能力に完全に依存するため、サーバーへの負荷が軽減されます。次に、高速であるため、どのフロントエンド実装を実装しても、パフォーマンスはバックエンドよりも優れています。第三に、実装が簡単です。バックエンドにウォーターマークを実装する最大のメリットも、安全・安心・安全の3点に集約されます。 Zhihu と Weibo はどちらもバックエンドの透かしソリューションを使用しています。ただし、総合的な検討の結果、透かしを実装するためにフロントエンド ソリューションを引き続き採用します。以下では、nodejs がバックエンド画像透かしを実装する方法についても簡単に紹介します。

ノード実装

3 つの npm パッケージを提供します。この部分はこの記事の焦点では​​なく、簡単なデモのみが提供されます。

1,

gm

https://github.com/aheckmann/gm 6.4k star

const fs = require('fs');
const gm = require('gm');


gm('/path/to/my/img.jpg')
.drawText(30, 20, "GMagick!")
.write("/path/to/drawing.png", function (err) {
  if (!err) console.log('done');
});
GraphicsMagick または ImageMagick のインストールが必要です;

2、

node-images

:https://github.com/zhangyuanwei/node-images

var images = require("images");

images("input.jpg")                     //Load image from file 
                                        //加载图像文件
    .size(400)                          //Geometric scaling the image to 400 pixels width
                                        //等比缩放图像到400像素宽
    .draw(images("logo.png"), 10, 10)   //Drawn logo at coordinates (10,10)
                                        //在(10,10)处绘制Logo
    .save("output.jpg", {               //Save the image to a file, with the quality of 50
        quality : 50                    //保存图片到文件,图片质量为50
    });
他のツールをインストールする必要はありません、軽量、zhangyuanwei によって開発されました、中国語、中国語のドキュメント;

3、

jimp

: https://github.com/oliver-moran/jimp を gifwrap とともに使用して、gif ウォーターマークを実装できます。

フロントエンドの実装

1、背景画像は全画面ウォーターマークを実装します

内部の個人情報ページで効果を確認できます。原則:

利点: 画像はバックエンドによって生成され、安全です; ウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析 欠点:画像情報を取得するために http リクエストを開始します;

エフェクト表示: 内部システムであるため、エフェクトを表示するのは不便です。

2、dom は画像全体のウォーターマークと画像ウォーターマークを実装します。

画像の onload イベントで画像の幅と高さを取得し、画像に応じてウォーターマーク領域を生成します。 DOM の内容はウォーターマークのコピーライティングやその他の情報であり、実装方法は比較的簡単です。

const wrap = document.querySelector('#ReactApp');
const { clientWidth, clientHeight } = wrap;
const waterHeight = 120;
const waterWidth = 180;
// 计算个数
const [columns, rows] = [~~(clientWidth / waterWidth), ~~(clientHeight / waterHeight)]
for (let i = 0; i < columns; i++) {
    for (let j = 0; j <= rows; j++) {
        const waterDom = document.createElement(&#39;div&#39;);
        // 动态设置偏移值
        waterDom.setAttribute(&#39;style&#39;, `
            width: ${waterWidth}px; 
            height: ${waterHeight}px; 
            left: ${waterWidth + (i - 1) * waterWidth + 10}px;
            top: ${waterHeight + (j - 1) * waterHeight + 10}px;
            color: #000;
            position: absolute`
        );
        waterDom.innerText = &#39;测试水印&#39;;
        wrap.appendChild(waterDom);
    }
}
利点: シンプルで実装が簡単;

欠点: 画像が大きすぎる、または多すぎるとパフォーマンスに影響します;

効果の表示:

#3、キャンバスの実装方法(初版実装案)

ウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析

方法1: 画像を直接操作する

これ以上の苦労はせずに、直接コードに進みましょう

useEffect(() => {
      // gif 图不支持
    if (src && src.includes(&#39;.gif&#39;)) {
      setShowImg(true);
    }
    image.onload = function () {
      try {
        // 太小的图不加载水印
        if (image.width < 10) {
          setIsDataError(true);
          props.setIsDataError && props.setIsDataError(true);
          return;
        }
        const canvas = canvasRef.current;
        canvas.width = image.width;
        canvas.height = image.height;
        // 设置水印
        const font = `${Math.min(Math.max(Math.floor(innerCanvas.width / 14), 14), 48)}px` || fontSize;
        innerContext.font = `${font} ${fontFamily}`;
        innerContext.textBaseline = &#39;hanging&#39;;
        innerContext.rotate(rotate * Math.PI / 180);
        innerContext.lineWidth = lineWidth;
        innerContext.strokeStyle = strokeStyle;
        innerContext.strokeText(text, 0, innerCanvas.height / 4 * 3);
        innerContext.fillStyle = fillStyle;
        innerContext.fillText(text, 0, innerCanvas.height / 4 * 3);
        const context = canvas.getContext(&#39;2d&#39;);
        context.drawImage(this, 0, 0);
        context.rect(0, 0, image.width || 200, image.height || 200);
           // 设置水印浮层
        const pattern = context.createPattern(innerCanvas, &#39;repeat&#39;);
        context.fillStyle = pattern;
        context.fill();
      } catch (err) {
        console.info(err);
        setShowImg(true);
      }
    };
    image.onerror = function () {
      setShowImg(true);
    };
  }, [src]);
長所: 純粋なフロントエンド実装、右クリックしてコピーした画像にも透かしが入ります;

短所: GIF はサポートされていません。画像はクロスドメインをサポートする必要があります;

効果の表示: 以下に示します。

方法 2: キャンバスはウォーターマーク URL を生成し、CSS 背景属性に割り当てます

export const getBase64Background = (props) => {
  const { nick, empId } = GlobalConfig.userInfo;
  const {
    rotate = -20,
    height = 75,
    width = 85,
    text = `${nick}-${empId}`,
    fontSize = &#39;14px&#39;,
    lineWidth = 2,
    fontFamily = &#39;microsoft yahei&#39;,
    strokeStyle = &#39;rgba(255, 255, 255, .15)&#39;,
    fillStyle = &#39;rgba(0, 0, 0, 0.15)&#39;,
    position = { x: 30, y: 30 },
  } = props;
  const image = new Image();
  image.crossOrigin = &#39;Anonymous&#39;;
  const canvas = document.createElement(&#39;canvas&#39;);
  const context = canvas.getContext(&#39;2d&#39;);
  canvas.width = width;
  canvas.height = height;
  context.font = `${fontSize} ${fontFamily}`;
  context.lineWidth = lineWidth;
  context.rotate(rotate * Math.PI / 180);
  context.strokeStyle = strokeStyle;
  context.fillStyle = fillStyle;
  context.textAlign = &#39;center&#39;;
  context.textBaseline = &#39;hanging&#39;;
  context.strokeText(text, position.x, position.y);
  context.fillText(text, position.x, position.y);
  return canvas.toDataURL(&#39;image/png&#39;);
};

// 使用方式 
<img  src="/static/imghwm/default1.png"  data-src="https://xxx.xxx.jpg"  class="lazy"   / alt="ウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析" >
<div className="warter-mark-area" style={{ backgroundImage: `url(${getBase64Background({})})` }} />

利点: 純粋なフロントエンド実装、クロスドメインのサポート、git イメージのサポートウォーターマーク;

欠点: 生成される Base64 URL は比較的大きい;

効果の表示: 以下に示されます。

実際、これら 2 つのキャンバスの実装に基づいて、3 番目の方法を簡単に思いつくことができます。これは、最初の方法で画像の上層を非画像キャンバスで覆うことです。この計画の欠点は、この 2 つの問題を完全に回避できることです。しかし、少し立ち止まって考えてみてください。2 つのソリューションを組み合わせて、キャンバスを使用して描画する、よりシンプルで簡単な方法はないだろうか?はい、代わりに svg を使用してください。

4、SVG メソッド (使用されているソリューション)

ウォーターマーク コンポーネントの反応バージョンを提供します。

export const WaterMark = (props) => {
  // 获取水印数据
  const { nick, empId } = GlobalConfig.userInfo;
  const boxRef = React.createRef();
  const [waterMarkStyle, setWaterMarkStyle] = useState(&#39;180px 120px&#39;);
  const [isError, setIsError] = useState(false);
  const {
    src, text = `${nick}-${empId}`, height: propsHeight, showSrc, img, nick, empId
  } = props;
  // 设置背景图和背景图样式
  const boxStyle = {
    backgroundSize: waterMarkStyle,
    backgroundImage: `url("data:image/svg+xml;utf8,<svg width=\&#39;100%\&#39; height=\&#39;100%\&#39; xmlns=\&#39;http://www.w3.org/2000/svg\&#39; version=\&#39;1.1\&#39;><text width=\&#39;100%\&#39; height=\&#39;100%\&#39; x=\&#39;20\&#39; y=\&#39;68\&#39;  transform=\&#39;rotate(-20)\&#39; fill=\&#39;rgba(0, 0, 0, 0.2)\&#39; font-size=\&#39;14\&#39; stroke=\&#39;rgba(255, 255, 255, .2)\&#39; stroke-width=\&#39;1\&#39;>${text}</text></svg>")`,
  };
  const onLoad = (e) => {
    const dom = e.target;
    const {
      previousSibling, nextSibling, offsetLeft, offsetTop,
    } = dom;
    // 获取图片宽高
    const { width, height } = getComputedStyle(dom);
    if (parseInt(width.replace(&#39;px&#39;, &#39;&#39;)) < 180) {
      setWaterMarkStyle(`${width} ${height.replace(&#39;px&#39;, &#39;&#39;) / 2}px`);
    };
    previousSibling.style.height = height;
    previousSibling.style.width = width;
    previousSibling.style.top = `${offsetTop}px`;
    previousSibling.style.left = `${offsetLeft}px`;
    // 加载 loading 隐藏
    nextSibling.style.display = &#39;none&#39;;
  };
  const onError = (event) => {
    setIsError(true);
  };
  return (
    <div className={styles.water_mark_wrapper} ref={boxRef}>
      <div className={styles.water_mark_box} style={boxStyle} />
      {isError
        ? <ErrorSourceData src={src} showSrc={showSrc} height={propsHeight} text="图片加载错误" helpText="点击复制图片链接" />
        : (
          <>
            <img src="/static/imghwm/default1.png"  data-src="https://img.php.cn/upload/image/323/319/107/1629255185289626.png?x-oss-process=image/resize,p_40"  class="lazy"  onLoad={onLoad} referrerPolicy="no-referrer" onError={onError} src={src} alt="图片显示错误" />
            <Icon className={styles.img_loading} type="loading" />
          </>
        )
      }
    </div>
  );
};

优点:支持 gif 图水印,不存在跨域问题,使用 repeat 属性,无插入 dom 过程,无性能问题;
缺点:。。。

dom 结构展示:

ウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析

5,效果图展示

canvas 和 svg 实现的效果在展示上没有很大的区别,所以效果图就一张图全部展示了。

ウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析

QA

问题一:

如果把 watermark 的 dom 删除了,图片不就是无水印了吗?

答案:

可以利用 MutationObserver 监听 water 的节点,如果节点被修改,图片也随之隐藏;

问题二:

鼠标右键复制图片?

答案:

全部的图片都禁用了右键功能

问题三:

如果从控制台的network获取图片信息呢?

答案:

此操作暂时没有想到好的解决办法,建议采用后端实现方案

总结

前端实现的水印方案始终只是一种临时方案,业务后端实现又耗费服务器资源,其实最理想的解决方式就是提供一个独立的水印服务,虽然加载过程中会略有延迟,但是相对与数据安全来说,毫秒级的延迟还是可以接受的,这样又能保证不影响业务的服务稳定性。

在每天的答疑过程中,也会有很多业务方来找我沟通水印遮挡风险点的问题,每次只能用数据安全的重要性来回复他们,当然,水印的大小,透明度,密集程度也都在不断的调优中,相信会有一个版本,既能起到水印的作用,也能更好的解决遮挡问题。

原文地址:https://segmentfault.com/a/1190000040425430

作者:ES2049 /卜露

更多编程相关知识,请访问:编程视频!!

以上がウォーターマークを実装するにはどうすればよいですか?透かしを実現するいくつかの方法の簡単な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は知乎で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
美图秀秀怎么加水印呢?分享美图秀秀添加水印方法!美图秀秀怎么加水印呢?分享美图秀秀添加水印方法!Mar 16, 2024 pm 09:55 PM

想知道美图秀秀怎么加水印吗?美图秀秀是一款非常好用的修图p图软件,提供抠图放在另一个图、改图片大小kb、去水印、换证件照底色、全屏加时间日期地点水印等功能,可以帮助用户快速的完成图片的制作。有用户制作了自己的图片不想被别人盗图想要铺满自己的水印,但不知道如何操作?小编现在为大家分享美图秀秀添加水印方法!喜欢就快来下载吧!一、美图秀秀怎么加水印呢?分享美图秀秀添加水印方法!1.打开在本站下载的美图秀秀2023版。美图秀秀2023版类别:拍摄美化下载美图秀秀2023版是一款功能丰富的图片美化和编辑软

剪映怎么去水印 怎么去除剪映水印剪映怎么去水印 怎么去除剪映水印Feb 22, 2024 pm 05:16 PM

打开剪映并选择模板,编辑好视频以后点击导出,点击无水印保存并分享。教程适用型号:iPhone13系统:iOS15.3.1版本:剪映6.8.0解析1打开剪映并选择一个剪辑模板。2点击打开模板后,点击右下角的剪同款选项。3从相册中选择照片填充片段并点击下一步。4如何点击页面右上角的导出选项。5最后点击无水印保存并分享就可以了。补充:剪映是什么软件1剪映是一款视频编辑软件,拥有全面的剪辑功能,可以变速、有滤镜和美颜效果,还有着丰富的曲库资源。自2021年2月起,剪映支持在手机移动端,Pad端,Mac电

Wink如何去视频水印Wink如何去视频水印Feb 23, 2024 pm 07:22 PM

Wink如何去视频水印?winkAPP中是有去除掉视频水印的工具,但是多数的小伙伴不知道wink中如何去除掉视频中的水印,接下来就是小编为玩家带来的Wink视频去水印方法图文教程,感兴趣的用户快来一起看看吧!Wink如何去视频水印1、首先打开winkAPP,在首页面专区中选择【去水印】功能;2、然后在相册中选择你需要去除水印的视频;3、接着选择视频之后,剪辑视频之后点击右上角【√】;4、最后点击如下图所示的【一键去印】之后点击【处理】即可。

扫描全能王去除水印怎么去除扫描全能王去除水印怎么去除Mar 05, 2024 pm 05:34 PM

去除水印是软件扫描全能王中的一个好用的工具,有些用户还不太清楚扫描全能王去除水印怎么去除,可以在保存界面点击编辑PDF中的去除水印即可闭,接下来就是小编为用户带来的去除水印方法的介绍,感兴趣的用户快来一起看看吧!扫描全能王使用教程扫描全能王去除水印怎么去除答:可以在保存界面点击编辑PDF中的去除水印详情介绍:1、进入软件,点击【相机】图标。2、拍摄扫描需要去水印的文件。3、点击【→】进入下一步。4、完成编辑后,点击【✓】。5、点击其中的【编辑PDF】。6、选择下方的【去除水印】即可。

小米14怎么设置拍照水印?小米14怎么设置拍照水印?Mar 18, 2024 am 11:00 AM

为了让拍摄出的照片更具个性和独特性,小米14提供了拍照水印设置。通过设置拍照水印,用户可以在拍摄的照片上添加图案、文字和标志,使得每一张照片都能更好地记录下珍贵的时刻和回忆。接下来,我们将介绍如何在小米14中设置拍照水印,让您的照片更加个性化和生动。小米14怎么设置拍照水印?1、首先点击“相机”。2、然后点击“设置”。3、接着找到水印,随后就可以开始拍摄了。

小米14Ultra如何去除水印?小米14Ultra如何去除水印?Feb 28, 2024 pm 02:28 PM

小米14Ultra是一款性能配置非常不错的全新机型,这款手机还采用了与众不同的外观设计,颜值更高辨识度也很不错,很多入手的消费者们想要了解一下小米14Ultra怎么去除水印?,下面本站小编就为大家介绍一下吧!小米14Ultra怎么去除水印?1.打开相机应用程序:找到并打开小米14上预装的相机应用程序。2.进入设置菜单:点击屏幕右下角或左下角(取决于您使用哪个版本)显示其他选项按钮。然后,在弹出菜单中选择“设置”。3.关闭水印选项:在设置菜单中,您将看到各种选项和参数。向下滑动直到找到“水印”选项

WPS文档怎么加水印你知道吗WPS文档怎么加水印你知道吗Mar 20, 2024 am 08:40 AM

在WPS文档中加水印可以保护著作权,以防自己的文件被别人盗用,而且现在到处都在宣传保密,WPS文档加水印还可以找到文档打印的来源,能够顺利的追溯到源头。不管是为了保护著作权还是为了保密,工作中的WPS文档加水印不管对自己还是别人都是有好处的。水印的加载有很多种方式,下面我们就分享一个简单的WPS文档怎么加水印的方法。1.打开WPS文档,点击工具栏中的【插入】栏的【水印】。2.点击【水印】旁边的倒立小三角形,里面有一些有水印模板。3.自定义一个水印,点击【+】。4.弹出一个对话框,在【内容】里面输

剪映如何去水印剪映如何去水印Feb 23, 2024 pm 04:09 PM

剪映去水印的方法:1、裁剪视频;2、模糊处理;3、遮盖水印。详细介绍:1、裁剪视频,如果水印位于视频的边角位置,可以通过裁剪视频的方式去除水印,打开剪映应用,导入需要去除水印的视频,在时间轴上找到需要裁剪的视频片段,点击“裁剪”功能,进入裁剪界面,调整裁剪框的大小和位置,确保裁剪框不包含水印部分,点击“应用”或“完成”按钮,保存裁剪后的视频;2、模糊处理等等。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。