
はじめに
本エントリは はてなエンジニア Advent Calendar 2025 の 42 日目の記事です。
昨日は id:mangano-ito の 2026 年ですね。年末大掃除で見つけた昔作った謎スクリプト "solitarize" を紹介します。 でした。
id:mangano-ito さんは年末にしっかりと大掃除をされていてさすがですね。
id:himura467 は『僕のヒーローアカデミア』のアニメがめでたく最終回を迎えたということで、年末をヒロアカとともに過ごしておりました。
分かる方は分かるかと思いますが、タイトルもかなりヒロアカに引っ張られています。
アイコン決まらない問題
先日大学の研究室の同期と話していて、社会に出る前にアイコンをユーザーと一対一に対応させる必要があるよね、という話をしました。
僕は 2026 年は Blog や X (旧 Twitter)、GitHub、カンファレンスでの登壇など外部への発信に力を入れる年にしようと意気込んでいるのですが、大半の方はユーザー名よりもアイコンでインターネット上の人を区別している (と思っている) ため、各種プラットフォームにおけるアイコンがバラバラだと同じ人として認識してもらいづらいという問題があります。
実際僕は現在 3 種類くらいのアイコンを使い分けており、かなりわかりづらい人間になってしまっているんじゃないかな、と危惧しています。



また、自分の写真をアイコンに使う場合は現実の被写体が変化 (老い) することによってアイコンと本人の見た目に食い違いが起こりやすく、混乱を招いてしまう恐れもあります。
先達に倣う
はてなエンジニアのアイコンを見てみると、id:motemen を筆頭に id:rokuokun、id:polamjag、id:ymse などモザイク調のアイコンを用いている方が何人かいらっしゃいます。
また、id:motemen はその特徴的なアイコンをコンテンツにされているのをよく見かけます。羨ましい。
airreader.hatenablog.com
ということで、誰でも id:motemen 風のアイコンを作成できる Zig ライブラリと Wasm を用いた Web ページを作りました。
Image Motemenizer の遊び方
↑のページにアクセスし、「Click to upload or drag and drop」と書いてある領域をクリックして png, jpg, bmp のいずれかのファイルを選択することで画像が id:motemen 風になります。
もちろんドラッグ&ドロップをすることでもファイルを選択できます。
処理は全てブラウザ上で完結している (外部との通信を必要としない) ため、プライベートな画像などでも安心してモザイク処理を行うことができるはずです。

Horizontal Blocks と Vertical Blocks を変更することで、モザイクの粒度を変更できます。
id:motemen を目指すなら 4x4。id:polamjag なら 16x16。
また、Color Space を変更することでモザイク処理を計算するための色空間を指定できます。
現在は RGB と Oklab の二つの色空間をサポートしています。
Oklab は人間の知覚により近い方法で色の計算を行うことができますが、実際にどのような違いが生まれるのかも是非触って体験してみてください。
変更を加えた画像は「Download Result」と書いてあるボタンからダウンロードできます (現在は png 形式のみサポート)。
png では DEFLATE という圧縮フォーマットが用いられているのですが、これは RLE などと同様に画像に含まれる繰り返しパターンに対して最適化されているため、同じサイズの画像でもモザイク処理をすると有意にファイルサイズを削減する*1ことができます。嬉しいですね。
Image Motemenizer の実装
実装に Zig を用いているのは、単純に好みです。
Zig でしか実現できない実装などは特になく、Rust などでも同じように実装すれば実現できると思います。
今回実装するにあたって、ImageMagick などの画像処理ライブラリに依存しない Zig ライブラリとして実現することを目標に作りました。
stb を再発明するのは流石にしんどいので唯一 stb にはお世話になっていますが、vendoring しているため依存ゼロの Zig ライブラリとして実現することができました。
Rgb 色空間と Oklab 色空間の座標変換を手で書いたり、画像ファイルを1ピクセルずつ塗っていく体験はなかなか味わい深くて良かったです。
余談ですが、Zig における Wasm のビルドはクロスコンパイルのターゲットを指定することで実現できます*2。
Wasm 向けのターゲットとしては wasm32-freestanding と wasm32-wasi があるのですが、本ライブラリにおいては wasm32-wasi をターゲットとしてクロスコンパイルを行っています。
もちろん wasm32-freestanding としてビルドできれば最高なのですが、stb が libc に依存している関係で malloc, free, realloc を wrap した実装を Zig 側で書く必要があり、できないことはないと思うんですが少し億劫だったので wasm32-wasi で妥協している、という感じです。
ブラウザ側で特に polyfill などを設定せずとも自分の環境では latest の Chrome, Safari はどちらも元気に動いていますが、何か不具合などあれば対応します。
気が向いたら wasm32-freestanding でビルドするように修正するかもしれません。
おわりに
本ライブラリを用いて生成した id:motemen 風アイコンによって、僕の SNS たちのアイコンの統一が無事進められています。
新アイコンになっても本年も何卒よろしくお願いいたします。


*1:手元の 512x512 ピクセルの png 画像をサイズそのままに 16x16 でモザイク処理を施したところ、276KB -> 9KB になりました
*2:Ref: https://ziglang.org/learn/overview/#cross-compiling-is-a-first-class-use-case








