世界一無駄な、画像をCSSで書き換えるジェネレーターを作った+検証

この記事は、[CSS Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/css)の19日目の記事です。

# まずはじめに
みなさんWebで画像を表示させるときどうしていますか?

基本は

```html
<img src="sample.png" />
```

これですよね。
それ以外にも画像を表示させる方法はいろいろ。

# 画像を表示させる方法

わりと使うのが`background-image`に指定してあげるやつ

```html
<div class="main-image"></div>

<style>
.main-image {
  background-image: url("http://...")
}
</style>
```

次はbase64エンコードされたやつを埋め込むやつ。
小さい画像なら埋め込んだ方がユーザ体験がよくなったり(?)するのでわりと使うことあるらしい(?)画像をbase64エンコードしてあげてその文字列を`src`内に書けば画像を表示できます。以下のエンコーダが便利です。

[Base64エンコーダー (画像を簡単に変換)](https://lab.syncer.jp/Tool/Base64-encode/)

```html
<img src="data:image/png;base64,xxxxx..." />
```

基本は上の３つぐらいだと思います。(SVGとか,canvasはさておき)

# 本編: box-shadowで画像を表示する

ところで、`box-shadow`を使うとドット絵がつくれます。

[CSSでドット絵を描く方法](http://wwx.jp/pure-css-dot)
[CSSでドット絵を描いてみよう](http://blog.creativeflake.com/2016/09/css.html)

話はわりと簡単で、**要素自体を透明にしちゃって影でピクセルを作っていこう**というそれだけのはなし。

これが

```html
<div class="pixel-art"></div>
<style>
.pixel-art {
  background: transparent;
  width: 10px;
  height: 10px;
  box-shadow:
    0 10px red,
    10px 20px blue,
    20px 10px green;
}
</style>
```

<img width="688" alt="スクリーンショット 2018-12-13 14.58.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/0faaf236-02cc-49cc-c06e-9e24920b363b.png">

こうなる。

**画像のピクセル全部打ったらbox-shadowだけで画像になるじゃん**っていうのが今回の話の原点。

というわけでジェネレーターをVue.jsを使ってつくってみた。

<p data-height="265" data-theme-id="0" data-slug-hash="oJjPXb" data-default-tab="js,result" data-user="redshoga" data-pen-title="CSS PixelArt Generator" class="codepen">See the Pen <a href="https://codepen.io/redshoga/pen/oJjPXb/">CSS PixelArt Generator</a> by いーふとイチオカ🔰(@redshoga) (<a href="https://codepen.io/redshoga">@redshoga</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

画像を入力すると画像のすべての画素を`box-shadow`に変換して、もとの画像が表示できるhtmlファイルが取得できるようになります。わりとCPUを食うので低スペPCの人はご注意。

# 比較実験: 表示

今回はプロ生ちゃんの画像を使います。(400x400[px]に切り抜いています)(PNG形式で192KB)

![puronama.png](https://qiita-image-store.s3.amazonaws.com/0/91558/d63c65a9-6071-4667-d784-2e6e7e4f8805.png)
© 2018 Pronama LLC

かわいい。

これを3つのソースで、表示を比較してみます。

1つめ、`<img>`使うやつ(74バイト+画像(192KB))

```html:normal.html
<!DOCTYPE html>
<html>
<body>
  <img src="./puronama.png">
</body>
</html>
```

<img width="644" alt="スクリーンショット 2018-12-13 15.21.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/1b6310a7-43d1-232d-d020-708dc98b411a.png">


2つめ、`backgroud-image`使うやつ(200バイト+画像(192KB))

```html:backgroud-image.html
<!DOCTYPE html>
<html>
<body>
  <div class="image"></div>
  <style>
    .image {
      width: 400px;
      height: 400px;
      background-image: url("./puronama.png")
    }
  </style>
</body>
</html>
```

<img width="644" alt="スクリーンショット 2018-12-13 15.21.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/8a551811-2144-5570-b253-b821af63ec7c.png">


3つめ、`box-shadow`で書くやつ(5.8MB)
ちなみに処理の都合上1px下にずらしてます。

```html:box-shadow.html
<div class="pixel-art"></div>
<style>
.pixel-art {
  background: transparent;
  width: 1px;
  height: 1px;
  box-shadow: 0px 1px rgba(255, 255, 255, 255), ...
}
```

<img width="644" alt="スクリーンショット 2018-12-13 15.21.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/fe2f1a6c-c64c-9627-fb83-23f9957214a3.png">

**表示が変わるはずはない。**

ちなみに`box-shadow`で書くやつを拡大するとしましまが見えたりします。`<img>`とかでちゃんと書くとブラウザかOSがここらへんをいい感じにやってたんだなあっと関心。

<img width="1408" alt="スクリーンショット 2018-12-13 15.28.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/991af6ff-268d-5c33-d874-248b93eb63e3.png">




# 比較実験: CPU使用率

やってて気が付いたのが`box-shadow`で画像を書くやつ。表示が遅すぎる。(当たり前だよなぁ)　それで画像の描画終了までのChrome DevToolsのPerformanceを見てみた。

1つめ、`<img>`使うやつ

<img width="1139" alt="スクリーンショット 2018-12-13 15.26.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/75896f5e-859b-a4ef-74d3-b628e01bdf51.png">

2つめ、`backgroud-image`使うやつ

<img width="1139" alt="スクリーンショット 2018-12-13 15.25.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/ca75610c-5056-0094-8946-6db1b2b6548e.png">

3つめ、`box-shadow`で書くやつ

<img width="1408" alt="スクリーンショット 2018-12-13 15.27.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/91558/0522aa3c-a993-bd64-7390-e963875155c8.png">

LoadingとPaintingに時間がだいぶかかってる。

そもそも、`<img>`使うやつと`backgroud-image`使うやつはローカルのファイルを引っ張って表示、それに対して`box-shadow`で書くやつは自分のコード自身に画像データが入っているので、なんともいえない比較ですね。

とにかく10倍程度描画速度に差があることがわかりました。(たぶんCPU性能に依存してます。)

# おわりに

CSSはアニメーションがいろいろできます。そのため、今回の作成したやつを使えば`box-shadow`にアニメーションをつけて...なんて使い方はしないですね。たぶん。

`box-shadow`で画像を描画するのはふたつの意味でヨウリョウが悪いですね。(おしり~~おわり~~)