6
2

More than 1 year has passed since last update.

透明で軽量な favicon.ico の Base64_Encode イメージ(16x16px, 1.2KB)と作り方【PHP】

Last updated at Posted at 2019-11-05

Base64 Encoded Blank And Transparent favicon.ico image

俺様 Web API のログを見ると、毎回 favicon.ico がブラウザからリクエストされている。

Failed to load resource: the server responded with a status of 404 (Not Found)

無視するのも気持ち悪いので透明なアイコンが欲しい。また、CSS にも埋め込めるように Base64 で欲しい。

つまり blanktransparentlightweight な 16x16 px の favicon.ico の Base64 文字列が欲しいのです。でも、オンラインのサービスで作成するのは、いささか不安なのです。

php lightweight favicon.ico Base64 blank」とググっても、ドンピシャな情報が出てこなかったので、未来の自分のググラビリティとして。

  • 合わせて読みたい

TL; DR (今北産業)

1. バイナリが欲しい人

2. 文字列で欲しい人

16x16pxの透過favicon.icoのBase64エンコード文字列
AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAA==
htmlに埋め込んじゃう方法
<head>
    <link rel="icon" type="image/vnd.microsoft.icon" href="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A////AP///wD///8A//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAA==">
</head>

🐒   最初 Content-Typeimage/x-icon にしていましたが image/vnd.microsoft.icon を指定するようにしました。これは ICO フォーマットの画像なため「IANA に登録された標準的な MIME タイプを用いることが望ましい」らしいからです。動いちゃうけど。

3. gzip 圧縮した favicon.ico の Base64 エンコード文字列で欲しい人

gzencode圧縮済みfavicon.icoのBase64_encode文字列
H4sIAAAAAAAAA2NgYARCAQEGIKnAkMHCwCDGwMCgAcRAIaAIRBwX+P///ygexaN4xGIGijAASeibMX4EAAA=

圧縮しなくても 1.2 KB(1,150 バイト)程度なのですが、サーバ側(PHP 側)で出力する場合、そのままだと記載が長くソースの可読性がいささか悪くなります。上記は gzencode で gzip 圧縮してから Base64 エンコードしたものです。記載が短く済みます。

gzip のまま送信する
「ブラウザが gzip 圧縮対応なら、そのまま送信しちゃった方がさらに軽いんじゃね?」という方は鋭い!下記コメント欄をご覧ください。キャッシュが効いたスパイシーな全部盛りの使用例があります。@vf8974 Thanks!

解凍方法
// Gzip 圧縮 & Base64 エンコード済み文字列
$base64_favicon = 'H4sIAAAAAAAAA2NgYARCAQEGIKnAkMHCwCDGwMCgAc'
                . 'RAIaAIRBwX+P///ygexaN4xGIGijAASeibMX4EAAA=';
// デコード&解凍
$str_compressed = base64_decode($base64_favicon);
$bin_image = gzdecode($str_compressed);

// 送信
header('Content-Type: image/vnd.microsoft.icon');
header('Content-Length: ' . strlen($bin_image));
echo $bin_image;

ちなみに、元となる favicon.ico の作成方法は TS;DR 参照。

TS; DR (限りなく透明なソースコード)

具体的な使用例
<?php

// Main
if (isRequestFaviconIco()) {
    echoFaviconAndExit();
}

// Functions
function echoFaviconAndExit()
{
    $bin_image = getFaviconImage();

    header('Content-Type: image/vnd.microsoft.icon');
    header('Content-Length: ' . strlen($bin_image));
    echo $bin_image;

    exit(0);
}

function getFaviconImage()
{
    $base64_favicon = 'H4sIAAAAAAAAA2NgYARCAQEGIKnAkMHCwCDGwMCgAc' .
                      'RAIaAIRBwX+P///ygexaN4xGIGijAASeibMX4EAAA=';
    $str_compressed = base64_decode($base64_favicon);

    return gzdecode($str_compressed);
}

function isRequestFaviconIco()
{
    if (isset($_SERVER['REQUEST_URI']) && ($_SERVER['REQUEST_URI']==='/favicon.ico')) {
        return true;
    }

    return false;
}
元favicon.icoイメージのHexDump
$ hexdump -C favicon.ico
00000000  00 00 01 00 01 00 10 10  00 00 01 00 20 00 68 04  |............ .h.|
00000010  00 00 16 00 00 00 28 00  00 00 10 00 00 00 20 00  |......(....... .|
00000020  00 00 01 00 20 00 00 00  00 00 00 00 00 00 00 00  |.... ...........|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 ff ff  |................|
00000040  ff 00 ff ff ff 00 ff ff  ff 00 ff ff ff 00 ff ff  |................|
*
00000440  00 00 ff ff 00 00 ff ff  00 00 ff ff 00 00 ff ff  |................|
*
00000470  00 00 ff ff 00 00 ff ff  00 00 ff ff 00 00        |..............|
0000047e

サイズは1.2KB
$ ls -l favicon.ico
-rw-r--r--@ 1 admin  staff  1150 11  5 15:22 favicon.ico

$ curl -s --head http://localhost:8080/favicon.ico | grep Content
Content-Type: image/vnd.microsoft.icon
Content-Length: 1150

favicon.ico の ICO 画像の作成と Base64 エンコード

PHP の GD と、イメージを ICO フォーマットに変換する PHP ICO クラスを使って ICO 画像を作成してみました。処理内容は以下の通り。

  1. 16x16 px の TrueColor キャンバスを白で埋める。
  2. アルファ値を MAX(127)にして透過にする。
  3. PHP ICO で ICO フォーマットに変換
  4. gzencode で圧縮
  5. base64_encode でテキスト化

所感

Docker コンテナ上の PHP のビルトイン Web サーバーで動かしている簡単な Web API を ngrokserveo 経由で公開する際に「favicon.ico ないよ 404 エラー」が気持ち悪かったので、これくらいは返してあげようと思いました。

普通にサイト上に favicon.ico ファイルを置いておけばいいのですが、ルータースクリプトphp -S localhost:8080 /app/index.phpindex.php)を指定しているので「どうせルータースクリプト内で分岐するなら、スクリプトで吐き出しちゃえばいいや」と思いました。

しかし、オンラインのサイトで作成した favicon.ico で、変なデータを入れられるのが嫌だったので、16x16px の透過 PNGを ICO 化したデータが欲しかったのです。

php lightweight favicon.ico Base64 blank」とググっても、ドンピシャな情報が出てきませんでした。

おそらく、苦労したことを忘れて同じことを検索すると思うので、コピペピピックな未来の自分へ向けた記事です。

6
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2