ブラウザだけで完結する画像マスクアプリ「もざいくにゃん」を作った話(React + Canvas + Cloudflare Pages)

概要

今回は、自分で作ったブラウザ完結型の画像モザイク&マスクツール「もざいくにゃん」について紹介していきます。
作ろうと思ったきっかけは、ごく日常的な「ちょっとした困りごと」でした。

  • 家族写真をSNSに上げたいけど、子どもや友人の顔は隠したい
  • ブログ用のスクショに、メアドや住所がうっかり写り込んでいた
  • フリマの商品写真に、配送ラベルの個人情報が残っていた

こういうとき、世の中には便利な画像加工サイトがたくさんあります。
ただ 「隠したい情報が写った画像を、他人のサーバーにアップロードする」という構造が、個人的にどうしても引っかかっていました。
隠したいから加工しているのに、その画像をネット越しに渡してしまうのは本末転倒ですよね(- -;

そこで 画像を一切サーバーに送らず、ブラウザの中だけで加工が完結することを最優先の設計方針にして作ったのが、このツールです。
この記事では「どう作ったか」を主軸に、React CDN・Canvas API・Cloudflare Pagesという低コストな構成と、実装で工夫したポイントを書いていきます。

それではやっていきましょう!

目次

どんなツールを作ったか

「もざいくにゃん」は、登録もインストールも不要で、URLを開くだけで使える無料の画像加工ツールです。

もざいくにゃんのトップページ。モザイクとマスクの2モードを持つ画像加工ツール
もざいくにゃんのトップページ。ブラウザ完結の無料画像モザイク・マスクツール

機能の中心は「モザイク」と「マスク」という性格の違う2つのモードです。
ここを分けたのが、このツールでいちばんこだわった部分になります!

  • モザイク ―「自然に」隠す
    • 人物の顔、背景の通行人、ナンバープレート、表札など。元の色味を残したままブロック状にぼかすので、隠しつつ雰囲気は壊さない
  • マスク ―「確実に」隠す
    • 住所・電話番号・金額・QRコード・APIキーなど。指定色できっぱり塗りつぶすので、元情報は絶対に復元できない

「自然に隠したいのか、確実に隠したいのか」で必要な処理はまったく別物です。
1枚の画像にモザイクとマスクを混在させることもできるので、たとえば「顔はモザイク、写り込んだ住所はマスク」といった使い分けもできます。

技術構成 ―「画像を端末から出さない」をどう実現したか

このツールの肝は、最初に書いた通り 画像をサーバーに送らないことです。
従来の画像加工サービスとの違いを図にすると、こうなります。

従来ツールはサーバーに画像を送って加工するのに対し、もざいくにゃんはブラウザ内のCanvasだけで処理する
従来ツールはサーバー送信、もざいくにゃんはブラウザ内Canvas処理という画像加工フローの対比図

加工処理はすべてブラウザのCanvas API上で行い、ファイルは端末の外に一切出ません。
この方針を軸に、技術スタックは「個人開発・低コスト・サーバーレス」で組みました。

  • 画像処理: Canvas API(100%クライアント処理)
    • 読み込んだ画像を <canvas> に描き、サーバーを介さずピクセル単位で加工する
  • UI: React 18 + Babel Standalone(CDNのみ)
    • ビルド工程を持たず、ブラウザ上でJSXをその場変換する構成。配信は静的ファイルだけで済む
  • HEIC対応: heic-to(自己ホスト・libheif同梱)
    • iPhoneのHEIC画像を、ブラウザ内でJPGへ自動変換してから加工する。変換ライブラリも外部CDNに頼らず同梱しているので、ここでも画像はネットに出ない
  • 設定の永続化: localStorage
    • 確定時の粗さ・色・外枠などを自動保存。次回も前回と同じ設定で始められる
  • ホスティング: Cloudflare Pages + Wrangler
    • wrangler pages deploy publicで静的サイトを無料枠にデプロイ。サーバー運用コストはゼロ
画像はネットワークを通らないので、ツール側に画像が保存されることはありません。
「隠したい情報が写った画像」を安心して扱える、という体験そのものが目的の設計です。

モザイクとマスクの実装の違い

2つのモードは、Canvas上でやっていることがそれぞれ違います。

  • モザイク: ブロックごとの色をならす
    • ドラッグで囲った範囲を一定サイズのブロックに区切り、各ブロックの色を平均化して塗り直す仕組みで、粗さスライダーはこのブロックサイズ(4〜80px)を変えているだけ
  • マスク: 塗りつぶし+外枠
    • 囲った範囲を指定色のベタ塗りで上書きする。さらにオプションで、周囲に色付きの枠線を足せるようにした

マスクに 外枠オプションを付けたのは、ブログのスクショで「ここは意図的に隠しました」という伏せ感を出したかったからです。
ただの黒塗りより、ピンクや青の枠で囲ったほうが「消し忘れ」ではなく「目隠し」だと一目で伝わるし、見た目もよいですよね(^^

テストはビジュアル回帰で担保

画像加工ツールは「見た目が崩れていないか」がそのまま品質になります。
そこでE2Eにはpuppeteer-core + pixelmatchを使い、加工後のCanvasを基準画像とピクセル比較するビジュアル回帰テストを入れました。
モザイクの粗さや外枠の描画がうっかり変わってしまっても、差分で気づけるようにしています。

使い方(4ステップ)

作った話が主役の記事ですが、実際の操作も簡単に紹介しておきます。
基本は アップロード → モード選択 → ドラッグで囲う → ダウンロードの4ステップです。

1. 画像をアップロードする

ドラッグ&ドロップ、またはタップ/クリックでファイルを選ぶだけです。
JPG / PNGに加えて、iPhoneのHEICにも対応しています。

エディタの最初の画面。画像をドロップするか、タップして選ぶだけで始められる
もざいくにゃんのエディタ画面。画像アップロード用のドロップゾーン

2〜3. モードを選び、ドラッグで囲う

右パネルのタブでモザイクとマスクを切り替え、隠したい部分を左上から右下へドラッグして囲います。
指を離すとその場で効果が適用され、何度でも追加できます。
間違えたら「1つ戻る」かCtrl+Zで取り消せます。

モザイクモードで顔をぼかした例。粗さはスライダーとプリセットで調整できる
もざいくにゃんでサンプル画像の顔にモザイクをかけた編集画面
マスクモードで配送ラベルの個人情報を塗りつぶした例。ピンクの外枠で「目隠し」を明示
もざいくにゃんでサンプル配送ラベルの個人情報をマスクし外枠を付けた編集画面
掲載しているサンプル画像(顔・配送ラベル)はすべて架空のダミーです。
実在の個人情報は含まれていません。

4. 確定してダウンロードする

「確定する」で加工を焼き付けたら、保存形式(PNG / JPG)を選んでダウンロードするだけです。
端末ごとに最適な保存導線を用意していて、iPhoneなら「写真に保存」、Androidなら「共有」からSNSへ直接シェアもできます。

確定後のダウンロード画面。PNG(高画質)かJPG(軽量)を選んで保存する
もざいくにゃんのダウンロード画面。PNGとJPGの保存形式を選択できる

こんな場面で使える

作りながら「自分ならこう使う」と想定していた場面を、いくつか挙げておきます。

  • 家族写真のSNS投稿
    • 子どもや友人の顔だけモザイク(20〜30px)で自然にぼかす
  • フリマの再出品
    • 配送ラベルの住所・氏名を白や黒のマスクで隠して、安全に写真を使い回す
  • 技術ブログのスクショ
    • APIキーやトークン、本番URLを黒マスク+色付き外枠で確実に目隠しする
  • 支払いQR・会員バーコード
    • 読み取れてしまうQRやバーコードを、塗りつぶしで完全に潰す

特に技術ブログを書く人には かなりお勧めです。
スクショに認証情報が写り込む事故は、よく聞く話なので、確実に防いでいきましょう(^^b

まとめ

「隠したい画像こそ、ネットに出したくない」という素朴な動機から、ブラウザ内で完結する画像マスクツールを作ってみました。

使いやすくて、セキュリティ面もばっちりなので、業務でもガンガン使っていこうと思います。

皆様も無料で登録も不要なので、顔やスクショの個人情報をサッと隠したいときに、ぜひ気軽に試してみてください!

ブラウザだけで完結する画像モザイク&マスクツール「もざいくにゃん」
mozaikunyan.shinpinoshi.comhttps://mozaikunyan.shinpinoshi.com/editor

以上となります。
個人情報漏洩は大事件なので、確実に回避しましょう!
それではお疲れさまでした!