【Vue.js】TOAST UI Image Editor を使って画像編集！

## はじめに
切り取りとモノクロ化、輝度調整できることから、TOAST UI Image Editorを使っており、
Qiitaにあまり記事がなかったので、今回利用方法をまとめてみました。

## TOAST UI Image Editorとは？
Canvasを利用した画像編集ライブラリで、主に以下の機能を提供しています。

- 画像アップロード機能
- 作成した画像のダウンロード
- 画像の切り取り
- 画像の反転、回転
- 図形の挿入、描画
- アイコン(アップロード可)、テキストの挿入
- 背景のマスク機能
- フィルタ機能(モノクロ、セピアなど)

## 参考情報
- tui-image-editor
　https://ui.toast.com/tui-image-editor/
- ソースコード
　https://github.com/ryuckel/vue-playground/tree/tui-image-editor

## 今回の記事のゴール
最小限の手数でTOAST UI Image Editorのフル機能を使えるようにするところをゴールとします。
作成していく中で必要なパラメータや詰まりやすい部分などは記事中に記載していきます。

![画面収録 2020-01-25 14.31.08.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125532/e9b2dbd2-fa4f-256a-c3ba-0fc108f76c86.gif)


## 環境
- Vue.js 2.5.10
- vue-cli 3.7.0
- toast-ui.vue-image-editor
<br>※Vue.js用に用意されたラッパーを使用して作成していきます。

## 実装（準備編）
- 環境構築
<br>vue createコマンドでプロジェクトを作成していきます。
<br>プロジェクト名は任意で入れてください。
<br>セットアップにあたり聞かれる質問も任意で答えていただいて構いません。

```
vue create image-editor-app(プロジェクト名を入れてください)
cd image-editor-app
```


- 必要なライブラリのインストール
<br>TOAST UI Image Editorの他に画像ダウンロード機能を使うため、
<br>file-saverをインストールします。
<br>~~※tui-image-editorの依存関係パッケージに含まれているのになぜかインストールしないと使えませんでした。。。~~ 
<br> ~~Issueで確認してますが、ご存知の方がもしいらっしゃればコメントください。。~~ 
<br>(2020.0212 追記)Issue投げたら、ローカルへのファイルダウンロードはfile-saverのインストールが必要とのことです。。

```
yarn add @toast-ui/vue-image-editor
yarn add file-saver
```

※補足
TOAST UI Image Editorの他にパッケージをインストール(今回はfile-saver)した場合、
yarn serveコマンド実行時などコンパイル実行時に必要なパッケージが足りない旨
コンパイルエラーが発生する場合があります。

その際は、エラーの内容に従ってエラーに表示されたパッケージを```yarn add```コマンドで
追加してあげることで解消します。
ライブラリ側の既知の問題とのことです。

## 実装(コンポーネント作成)
TOAST UI Image Editorを使ったコンポーネントを作成していきます。
パラメータが多く、localeは一部だけ記載します。全部見たい方はGithubのソースをご覧ください。

要点と注意ポイントは以下の通りです。

- useDefauleUIをtrueにしてPropsで渡すことでデフォルトのUIの適用し、カスタムする部分はoptionsに指定してPropsで値を渡す
- コンポーネントにはライブラリの他に、スタイルを適用させるために、tui-image-editor.cssとアイコンをimportする
- 各要素のスタイルは変数(下記ではtheme)に格納したうえでoptions>includeUIのthemeに指定すると適用される
- ロケールも各要素に文言を指定した変数(下記ではlocale_ja)に格納したうえでoptions>includeUIのlocaleに指定する


```imageEditor.vue
<template>
  <tui-image-editor ref="tuiImageEditor" :include-ui="useDefaultUI" :options="options"></tui-image-editor>
</template>

<script>
//ライブラリのインポート
import { ImageEditor } from "@toast-ui/vue-image-editor";

// アイコンのインポート
import icon_a from "tui-image-editor/dist/svg/icon-a.svg";
import icon_b from "tui-image-editor/dist/svg/icon-b.svg";
import icon_c from "tui-image-editor/dist/svg/icon-c.svg";
import icon_d from "tui-image-editor/dist/svg/icon-d.svg";

// ライブラリ側で用意しているスタイルの読み込み
import "tui-image-editor/dist/tui-image-editor.css";

// ダウンロード機能を使う際はインポートする
import "file-saver";

//ロケールの設定。自分で日本語に訳して入れていく
const locale_ja = {
  Load: "ファイル選択",
  Download: "ダウンロード",
  Apply: "適用",
  Arrow: "矢印",
  "Arrow-2": "矢印2",
  "Arrow-3": "矢印3"...
}
//表示される各要素のスタイルを指定
var theme = {
  //共通のスタイル
  "common.bi.image": "",
  "common.bisize.width": "0px",
  "common.bisize.height": "0px",
  "common.backgroundImage": "none",
  "common.backgroundColor": "#FFFFFF",
  "common.border": "0px",
  // ヘッダー
  "header.backgroundImage": "none",
  "header.backgroundColor": "transparent",
  "header.border": "0px",
  // ファイルアップロードボタンのスタイル
  "loadButton.backgroundColor": "#fff",
  "loadButton.border": "1px solid #ddd",
  "loadButton.color": "#222",
  "loadButton.fontFamily": "NotoSans, sans-serif",
  "loadButton.fontSize": "12px",
  // ダウンロードボタンのスタイル
  "downloadButton.backgroundColor": "#fdba3b",
  "downloadButton.border": "1px solid #fdba3b",
  "downloadButton.color": "#fff",
  "downloadButton.fontFamily": "NotoSans, sans-serif",
  "downloadButton.fontSize": "12px",
  // メインアイコン
  "menu.normalIcon.path": icon_d,
  "menu.activeIcon.path": icon_b,
  "menu.disabledIcon.path": icon_a,
  "menu.hoverIcon.path": icon_c,
  // サブメニューアイコン
  "submenu.normalIcon.path": icon_d,
  "submenu.activeIcon.path": icon_c,
  // submenu primary color
  "submenu.backgroundColor": "#ffffff",
  "submenu.partition.color": "#858585",
  // サブメニュー
  "submenu.normalLabel.color": "#858585",
  "submenu.normalLabel.fontWeight": "lighter",
  "submenu.activeLabel.color": "#000",
  "submenu.activeLabel.fontWeight": "lighter",
  // チェックボックス
  "checkbox.border": "1px solid #ccc",
  "checkbox.backgroundColor": "#fff",
  // 切り取り
  "range.pointer.color": "#000",
  "range.bar.color": "#666",
  "range.subbar.color": "#d1d1d1",
  "range.value.color": "#000",
  "range.value.fontWeight": "lighter",
  "range.value.fontSize": "11px",
  "range.value.border": "1px solid #353535",
  "range.value.backgroundColor": "#151515",
  "range.title.color": "#000",
  "range.title.fontWeight": "lighter",
  // colorpicker 
  "colorpicker.button.border": "1px solid #1e1e1e",
  "colorpicker.title.color": "#fff"
};

export default {
  name: "ImageEditor",
  components: {
    "tui-image-editor": ImageEditor
  },
  props: {},
  data() {
    return {
      useDefaultUI: true,
      options: {
        cssMaxWidth: document.documentElement.clientWidth,
        cssMaxHeight: document.documentElement.clientHeight,
        includeUI: {
          //表示メニューの設定。デフォルトでは全て表示される
          //menu: ["flip", "crop", "rotate", "filter"],
          //コンポーネント生成時に選択されるメニューの指定
          initMenu: "filter",
          //メニューバーの位置の指定
          menuBarPosition: "buttom"
          uiSize: {
            width: "100%",
            height: "650px"
          },
          theme: theme,
          locale: locale_ja,
        }
      }
    };
  }
};
</script>

```

## 注意点
モバイルのUIも用意されているのですが、レスポンシブ対応ができない？模様です。
できたら追記しようと考えています。

## 最後に
あまり知られていないのか、Qiita含めて記事も少なく、いくつかつまづいてしまったのですが
少しでもお役に立てれば嬉しいです。

機能は最低限網羅していますが、↑で紹介した以外にもデザインテーマをライブラリ側で用意していたり、
パラメータもあるのでぜひお試しください！