js を使用して画像をモザイク化する方法の例

js を使用して画像をモザイク化する方法の例

この記事では、主に js を使用して画像をモザイク化する方法の例を紹介し、次のように共有します。

効果のデモンストレーション

ここに画像の説明を挿入

キャンバスの紹介

この HTML 要素は、クライアント側のベクター グラフィック用に設計されています。独自の動作はありませんが、クライアント側の JavaScript に描画 API を公開し、スクリプトがキャンバス上に必要なものを描画できるようにします。

HTML5タグは、画像を描画するために使用されます(スクリプト、通常はJavaScript経由)

ただし、要素自体には描画機能はありません (単なるグラフィックのコンテナーです)。実際の描画を行うにはスクリプトを使用する必要があります。

getContext() メソッドは、キャンバスに描画するためのメソッドとプロパティを提供するオブジェクトを返します。

このマニュアルでは、キャンバス上にテキスト、線、四角形、円などを描画するために使用できる getContext("2d") オブジェクトのプロパティとメソッドの完全なセットを提供します。

マークアップと SVG および VML の違い:

マークアップと SVG および VML との重要な違いは、JavaScript ベースの描画 API があるのに対し、SVG および VML は描画を記述するために XML ドキュメントを使用することです。

これら 2 つのアプローチは機能的に同等であり、どちらか一方を他方でシミュレートできます。表面的には非常に異なりますが、それぞれに長所と短所があります。たとえば、SVG 図面は、説明から要素を削除するだけで簡単に編集できます。

同じ図のマークアップから要素を削除するには、多くの場合、図面を消去して再描画する必要があります。

ここに画像の説明を挿入

ナレッジポイントの紹介

js を使用して画像を作成する

img = new Image() とします。
//画像にリンクを付けることができます img.src = 'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=826495019,1749283937&fm=26&gp=0.jpg'
//または既存のローカル画像のパス//img.src = './download.jpg'

//HTMLに追加 document.body.appendChild(img)

キャンバス.getContext("2d")

文法:
contextID パラメータは、キャンバス上で実行する描画の種類を指定します。現在、有効な値は「2d」のみで、これは 2 次元描画を指定し、このメソッドが 2 次元描画 API をエクスポートする環境オブジェクトを返すようにします。

ctx = Canvas.getContext(コンテキストID) とします。

ctx.drawImage()

JavaScript 構文 1:
キャンバス上に画像を配置します。

context.drawImage(画像,x,y);

JavaScript 構文 2:
キャンバス上に画像を配置し、幅と高さを指定します。

context.drawImage(画像、x、y、幅、高さ);

JavaScript 構文 3:
画像を切り抜き、切り抜いた部分をキャンバス上に配置します。

JavaScript 構文
getImageData() メソッドは、キャンバスの指定された四角形のピクセル データをコピーする ImageData オブジェクトを返します。
ImageData オブジェクトの各ピクセルには、RGBA 値という 4 つの情報があります。
R - 赤 (0-255)
G - 緑 (0-255)
B - 青 (0-255)
A - アルファ チャネル (0 ~ 255、0 は透明、255 は完全に表示されます)
色/アルファは配列形式で存在し、ImageDataオブジェクトのデータプロパティに格納されます。

var imgData = context.getImageData(x,y,幅,高さ);

ctx.putImageData()

putImageData() メソッドは、画像データ (指定された ImageData オブジェクトから) をキャンバスに戻します。

次に、この小さな機能を完了するために、ステップバイステップで説明してください〜

ここに画像の説明を挿入

ステップバイステップ

イメージを準備し、メソッドを追加します

<本文>
    <img src="./download.jpg">
    <button onclick="addCanvas()">キャンバスを生成</button>
    <button onclick="generateImg()">画像を生成</button>
</本文>

ここに画像の説明を挿入

次にaddCanvasメソッドを記述します

関数addCanvas() {
		bt = document.querySelector('button') とします。

        let img = new Image(); //1. 画像をコピーする準備をする img.src = './download.jpg'; 
        img.onload = function() { //2. 画像が読み込まれるのを待ちます。let width = this.width
            高さを this.height とします
			
			let canvas = document.createElement('canvas') //3. キャンバスを作成します。let ctx = canvas.getContext("2d"); //4. キャンバスのコンテンツを取得します。canvas.setAttribute('width', width) //5. 統一性を保つために、キャンバスの幅と高さを画像の幅と高さに設定します。canvas.setAttribute('height', height)
   
            ctx.drawImage(this, 0, 0, width, height); //5. キャンバスに画像を描画します document.body.insertBefore(canvas, bt) //5. ボタンの前にキャンバスを挿入します}
    }

キャンバスに画像を正常に取得しました:

ここに画像の説明を挿入

さて、成功に向けて小さな一歩を踏み出しましたが、次は何をすべきでしょうか? …さて、マウスを押すプロセスを表すにはネイティブのonmouseupイベントとonmousedownイベントを使用する必要がありますが、これらの 2 つのイベントはどこに追加すればよいでしょうか?

そうです、キャンバス上でモザイク操作を実行したいので、これらの2つのイベントをキャンバス要素に追加する必要があります。

キャンバスを作成するプロセスが少し複雑であることを考慮して、モジュールのカプセル化を作成しましょう。

関数addCanvas() {
        bt = document.querySelector('button') とします。

        img = new Image();
        img.src = './download.jpg'; //ここに自分の写真を入れてください img.onload = function() {
            幅 = this.width とします
            高さを this.height とします

            させて {
                キャンバス、
                ctx
            } = createCanvasAndCtx(width, height) //オブジェクトの分解はキャンバスとctxを受け取ります

            ctx.drawImage(this, 0, 0, 幅, 高さ);

            document.body.insertBefore(キャンバス、bt)

        }
    }

    関数createCanvasAndCtx(幅, 高さ) {
        キャンバスを document.createElement('キャンバス') にします。
        キャンバス.setAttribute('幅', 幅)
        キャンバス.setAttribute('height', 高さ)
        canvas.setAttribute('onmouseout', 'end()') //マウスがキャンバスから離れないように修正 canvas.setAttribute('onmousedown', 'start()') //マウスダウンを追加 canvas.setAttribute('onmouseup', 'end()') //マウスアップを追加 let ctx = canvas.getContext("2d");
        戻る {
            キャンバス、
            ctx
        }
    }

	関数開始() {
            キャンバスを document.querySelector('キャンバス') にします。
            キャンバス.onmousemove = () => {
                console.log('マウスを押して動かしました')
            }
        }

        関数終了() {
            キャンバスを document.querySelector('キャンバス') にします。
            キャンバス.onmousemove = null
        }

start()end()が有効かどうかをテストする

ここに画像の説明を挿入

さて、この時点では、コードはまだ期待どおりに動作しています。

次の課題はより困難です。ピクセルを取得して処理する必要があります。start() 関数をもう一度書き直してみましょう。

関数開始() {
    img = document.querySelector('img') とします。
    キャンバスを document.querySelector('キャンバス') にします。
    ctx = canvas.getContext("2d"); とします。
    imgData = ctx.getImageData(0, 0, img.clientWidth, img.clientHeight);
    キャンバス.onmousemove = (e) => {
        let w = imgData.width; //1. 画像の幅と高さを取得します。let h = imgData.height;

        //モザイクの度合い。数字が大きいほどぼやけます。let num = 10;

        //マウスが現在位置するピクセルのRGBAを取得します
        color = getXY(imgData, e.offsetX, e.offsetY);

        (k = 0; k < num; k++) の場合 {
            (l = 0; l < num; l++) の場合 {
                //座標 (e.offsetX + l, e.offsetY + k) で imgData の色を設定します。setXY(imgData, e.offsetX + l, e.offsetY + k, color);
            }
        }
        //キャンバスデータを更新 ctx.putImageData(imgData, 0, 0);
    }
}

//ここにはsetXYとgetXYという2つの関数があります。興味があれば、取得の原理を学ぶことができます。function setXY(obj, x, y, color) {
    var w = obj.width;
    var h = obj.height;
    var d = obj.data;
    obj.data[4 * (y * w + x)] = color[0];
    obj.data[4 * (y * w + x) + 1] = color[1];
    obj.data[4 * (y * w + x) + 2] = color[2];
    obj.data[4 * (y * w + x) + 3] = color[3];
}

関数 getXY(obj, x, y) {
    var w = obj.width;
    var h = obj.height;
    var d = obj.data;
    var color = [];
    色[0] = obj.data[4 * (y * w + x)];
    色[1] = obj.data[4 * (y * w + x) + 1];
    色[2] = obj.data[4 * (y * w + x) + 2];
    色[3] = obj.data[4 * (y * w + x) + 3];
    色を返します。
}

さて、成功はそう遠くありません。最後のステップは画像を生成することです。

幸いなことに、canavs はキャンバスを Base64 でエンコードされた画像として直接エクスポートする直接的な方法を提供します。

関数generateImg() {
    キャンバスを document.querySelector('キャンバス') にします。
    var newImg = 新しい画像();
    newImg.src = canvas.toDataURL("image/png");
    document.body.insertBefore(新しい画像、キャンバス)
}

最終結果:

ここに画像の説明を挿入

とても簡単でしょう? 手書きのコードが次のコードと同じかどうか確認してみましょう。

完全なコード

<!DOCTYPE html>
<html lang="ja">

<ヘッド>
    <メタ文字セット="UTF-8">
    <meta http-equiv="X-UA-compatible" content="IE=edge">
    <meta name="viewport" content="width=デバイス幅、初期スケール=1.0">
    <title>ドキュメント</title>
</head>

<本文>

    <本文>
        <img src="./download.jpg">
        <button onclick="addCanvas()">キャンバスを生成</button>
        <button onclick="generateImg()">画像を生成</button>
    </本文>
    <スクリプト>
        関数addCanvas() {
            bt = document.querySelector('button') とします。

            img = new Image();
            img.src = './download.jpg'; //ここに自分の写真を入れてください img.onload = function() {
                幅 = this.width とします
                高さを this.height とします

                させて {
                    キャンバス、
                    ctx
                } = createCanvasAndCtx(幅, 高さ)

                ctx.drawImage(this, 0, 0, 幅, 高さ);

                document.body.insertBefore(キャンバス、bt)

            }
        }

        関数createCanvasAndCtx(幅, 高さ) {
            キャンバスを document.createElement('キャンバス') にします。
            キャンバス.setAttribute('幅', 幅)
            キャンバス.setAttribute('height', 高さ)
            キャンバス.setAttribute('onmouseout', 'end()')
            キャンバス.setAttribute('onmousedown', 'start()')
            キャンバス.setAttribute('onmouseup', 'end()')
            ctx = canvas.getContext("2d"); とします。
            戻る {
                キャンバス、
                ctx
            }
        }

        関数開始() {
            img = document.querySelector('img') とします。
            キャンバスを document.querySelector('キャンバス') にします。
            ctx = canvas.getContext("2d"); とします。
            imgData = ctx.getImageData(0, 0, img.clientWidth, img.clientHeight);
            キャンバス.onmousemove = (e) => {
                let w = imgData.width; //1. 画像の幅と高さを取得します。let h = imgData.height;

                //モザイクの度合い。数字が大きいほどぼやけます。let num = 10;

                //マウスが現在位置するピクセルのRGBAを取得します
                color = getXY(imgData, e.offsetX, e.offsetY);

                (k = 0; k < num; k++) の場合 {
                    (l = 0; l < num; l++ とします) {
                        //座標 (e.offsetX + l, e.offsetY + k) で imgData の色を設定します。setXY(imgData, e.offsetX + l, e.offsetY + k, color);
                    }
                }
                //キャンバスデータを更新 ctx.putImageData(imgData, 0, 0);
            }
        }

        関数generateImg() {
            キャンバスを document.querySelector('キャンバス') にします。
            var newImg = 新しい画像();
            newImg.src = canvas.toDataURL("image/png");
            document.body.insertBefore(新しい画像、キャンバス)
        }

        関数setXY(obj, x, y, color) {
            var w = obj.width;
            var h = obj.height;
            var d = obj.data;
            obj.data[4 * (y * w + x)] = color[0];
            obj.data[4 * (y * w + x) + 1] = color[1];
            obj.data[4 * (y * w + x) + 2] = color[2];
            obj.data[4 * (y * w + x) + 3] = color[3];
        }

        関数 getXY(obj, x, y) {
            var w = obj.width;
            var h = obj.height;
            var d = obj.data;
            var color = [];
            色[0] = obj.data[4 * (y * w + x)];
            色[1] = obj.data[4 * (y * w + x) + 1];
            色[2] = obj.data[4 * (y * w + x) + 2];
            色[3] = obj.data[4 * (y * w + x) + 3];
            色を返します。
        }

        関数終了() {
            キャンバスを document.querySelector('キャンバス') にします。
            キャンバス.onmousemove = null
        }
    </スクリプト>
</本文>

</html>

もちろん、もっといろいろな創作ができます。例えば、上のモザイクは正方形ですが、数学の知識を使って円形にして、円の中心をマウスの中心にして広げることもできます。

いくつかのプロセスを改善することもできます。たとえば、モザイクの位置が間違っている場合は、キャンバスをクリアしてやり直すことができます。
または、画像をエクスポートした後に後処理を行ってキャンバスを非表示にする

js を使って画像をモザイクする例についての記事はこれで終わりです。より関連性の高い js 画像モザイクコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • 画像をモザイク化する Three.js サンプル コード
  • JavaScriptを使用して画像モザイクを表示し、テキスト機能を追加する
  • モザイク後の画像を表示および切り替えるにはJavaScriptを使用します

<<:  Docker を使用して Spring Boot をデプロイする方法

>>:  MySQL 8.0.11 の詳細なインストール手順

推薦する

初心者向け入門チュートリアル④:サブディレクトリのバインド方法

これが何を意味するのかを理解するには、まずサブディレクトリとは何かを知る必要があります。では、サブデ...

HTML テーブル マークアップ チュートリアル (39): ヘッダーの明るい境界線の色属性 BORDERCOLORLIGHT

テーブル ヘッダーでは、明るい境界線の色を個別に定義できます。基本的な構文<TH ボーダーカラ...

Zabbix を使用して Nginx/Tomcat/MySQL を監視する方法の詳細なチュートリアル

目次ZabbixはNginxを監視するZabbixはTomcatを監視するZabbixはMySQLを...

JDKネイティブスレッドプールのバグを修正するTomcatの実装原理

処理能力と同時実行性を向上させるために、Web コンテナは通常、リクエストを処理するタスクをスレッド...

dockerでnginxを実行するときにdaemon offが使用される理由についての簡単な説明

とても嬉しいです。この問題に遭遇したとき、私はDockerコンテナのプロセス原理について話さなければ...

MySQL ストレステストツールの使い方

1. MySQL 独自のストレステストツール - Mysqlslap mysqlslap は、mys...

CSS で 2 列レイアウトを実現する N 通りの方法

1. 2 列レイアウトとは何ですか? 2 列レイアウトには、左側が固定幅で右側が適応幅のレイアウトと...

el-table のテーブルを最適化するために仮想リストを使用する方法についての簡単な説明

目次序文解決具体的な実装満たすべき前提条件質問序文テーブルをよく使用します。データ量が多い場合は直接...

MySQLの自己接続と結合の詳細な理解

1. MySQL 自己接続MySQL では、情報を照会するときに自分自身に接続 (自己接続) する必...

JavaScript でのプロキシの使用を理解するための記事

目次エージェントとは何かプロキシの基礎知識ハンドラオブジェクトのメソッドプロキシでできること参考文献...

CSS での配置の使用方法の詳細な研究 (要約)

CSS における位置指定の概要position属性は英語で位置を意味し、 CSSでの主な機能は要素...

Vueはカードフリップ効果を実現します

この記事では、カードフリップ効果を実現するためのVueの具体的なコードを例として紹介します。具体的な...

MySQL バッチ挿入ループの詳細なサンプルコード

背景数日前、MySql でページングを行っていたときに、ページングに制限 0,10 を使用するとデー...

MySQLの浅いエントリと深いエグジットの原則についての簡単な説明

目次1. ページの概要2. 下限と上限3. ページディレクトリを使用する4. ページの実際の外観4....

Ant Design Blazor コンポーネントライブラリのルーティング再利用マルチタブ機能

最近、Ant Design Blazor コンポーネント ライブラリにマルチタブ コンポーネントを実...