[Julia] Juno, VSCode のプロットペインが表示できる画像形式

2020/8/22 VSCode の説明を追加したため、『Julia / Juno で画像を表示する』から改題

# Juno で HTML を表示するには？

以前の記事の補足のような位置づけで読んでほしい。

Julia / Jupyter での画像表示を実装する
https://qiita.com/Lirimy/items/b5604b41247ba8ca7a00

**ポイント**：
`MIME"text/html"` に当たる部分を
`MIME"application/prs.juno.plotpane+html"` に変更すればOK。
https://docs.junolab.org/latest/man/info_developer/#Displaying-Plots-and-Graphics-1

# 出力側が対応しているデータ形式

## Jupyter の仕様

```julia:display.jl
const ijulia_mime_types = Vector{Union{MIME, AbstractVector{MIME}}}([
    MIME("text/plain"),
    MIME("image/svg+xml"),
    [MIME("image/png"),MIME("image/jpeg")],
    [
        MIME("text/markdown"),
        MIME("text/html"),
    ],
    MIME("text/latex"),
])
```

https://github.com/JuliaLang/IJulia.jl/blob/master/src/display.jl

## Juno の仕様

```julia:showdisplay.jl
const plain_mimes = [
  "image/png",
  "image/jpeg",
  "image/tiff",
  "image/bmp",
  "image/gif"
]

const plotpane_mime = "application/prs.juno.plotpane+html"
const jlpane_mime = "application/prs.juno.jlpane"

# "image/svg+xml" は別のところで処理される
```

https://github.com/JunoLab/Atom.jl/blob/master/src/display/showdisplay.jl

## VSCode の仕様

```julia
const DISPLAYABLE_MIMES = [
    "application/vnd.vegalite.v4+json",
    "application/vnd.vegalite.v3+json",
    "application/vnd.vegalite.v2+json",
    "application/vnd.vega.v5+json",
    "application/vnd.vega.v4+json",
    "application/vnd.vega.v3+json",
    "application/vnd.plotly.v1+json",
    "juliavscode/html",
    # "text/html", # 非対応
    "image/svg+xml",
    "image/png"
]
```

https://github.com/julia-vscode/julia-vscode/blob/master/scripts/packages/VSCodeServer/src/display.jl#L96

`"text/html"` を受け付けないので注意。`"juliavscode/html"` を使う。

### Plots の GIF アニメを VSCode のプロットペインに表示する

```julia
using Plots

function Base.show(io::IO, ::MIME"juliavscode/html", agif::Plots.AnimatedGif)
    show(io, MIME("text/html"), agif)
end

# mp4 などはプロットペインに表示できないため無効化する
function Base.showable(::MIME"juliavscode/html", agif::Plots.AnimatedGif)
    Plots.file_extension(agif.filename) == "gif"
end

agif = @gif for k in 0:0.2:2
    plot(x->sinpi(x+k), 0:0.01:2)
end

display(agif)
```

この PR で `"image/gif"` を直接受け取れるようになるまでの暫定的な措置として。
https://github.com/julia-vscode/julia-vscode/pull/1554

# 対応する MIME 一覧

Jupyter / Juno / VSCode で出力できるデータ形式と対応する MIME をまとめた。
（ここで挙げた MIME 以外で出力できる場合もある。）

| Data format    | MIME (Jupyter) | MIME (Juno)                           | MIME (VSCode)       |
| -------------- | -------------- | ------------------------------------- | ------------------- |
| PNG            | image/png      | image/png                             | image/png           |
| SVG            | image/svg+xml  | image/svg+xml                         | image/svg+xml       |
| JPEG           | image/jpeg     | image/jpeg                            | juliavscode/html *1 |
| BMP            | text/html *1   | image/bmp                             | juliavscode/html *1 |
| GIF            | text/html *1   | image/gif                             | juliavscode/html *1 |
| MP4            | text/html *1   | application/prs.juno.plotpane+html *1 | 非対応 *2 |
| WebM           | text/html *1   | application/prs.juno.plotpane+html *1 | 非対応 *2 |

*1 Base64 エンコードして HTML タグで囲む。
*2 VSCode の Electron が ffmpeg を含まないため（ポリシーに基づく？）
https://stackoverflow.com/a/51735036