【魅惑ライブラリ試用①】高速かつ多機能な画像処理ライブラリ「sharp」を試用。

- 日常に溶け込み、多大なる恩恵を頂いているライブラリやパッケージを心おきなく試用する記事第一弾。
- 至近距離で、「個人開発者の、成果プロダクトがOSS化した時の、至極の表情」を拝みたいと切望する日常。
- 今回は、豊富な画像処理群が用意されているnpmパッケージ「sharp」を試用することにしよう。

## 概要
- JavaScript製の画像処理ライブラリ。
- 類似ライブラリとして、「[jimp](https://github.com/oliver-moran/jimp)」というパッケージがある。
- [公式Github](https://github.com/lovell/sharp)
- [公式ドキュメント](http://sharp.pixelplumbing.com/en/stable/)

## 特徴

### 多くの画像形式に対応
- jpgやpngだけでなく、webpやsvg等の多くの画像形式に対応している。
- 対応形式は[こちら](http://sharp.pixelplumbing.com/en/stable/#formats)で確認。

### 処理速度が高速
- 類似ライブラリの[jimp](https://github.com/oliver-moran/jimp)と比較して、処理速度が極めて高速である。

### 様々な画像処理機能を用意
- 「形式変換やリサイズ」等の基礎的なものから、「合成」等の複雑な処理までを網羅している。

## 結果
- 下記のように、画像ファイル名を指定して、簡単なjsファイルを実行するだけで、画像変換が可能。

<img width="635" alt="test2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/205d7e1b-aef1-1cee-a82a-44f47233f118.png">

- 下記のように、形式変換以外にも基礎的な画像処理(例:回転)が可能

<img width="728" alt="test3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/420fe7bc-830f-fb47-3056-d729e0d3b602.png">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/e4d2b58d-4bc2-89f8-3ae9-2edaa2ac9290.png)

- 下記のように、複数画像の素早い合成処理も可能。

<img width="837" alt="test88.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/595360c7-f9c3-80e2-877f-d15120a73c13.png">


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/8eec0c79-9ccd-5ee2-8699-224dd6c001ee.png)


## 環境
- Mac OS X 10.13.4
- NodeJs v11.6.0
- npm 6.9.0
- **※今回はコマンドを利用した画像処理試用のため、Webアプリケーションへの組み込みは行わない。**

## インストール
- **※sharpは、Node.jsを利用するため、インストールが未完了の場合、[こちら](https://www.sejuku.net/blog/72545)を参考にインストールする。**

### npmでのインストール
- Node.jsパッケージ管理の`npm`でのインストールの場合、下記のコマンドをうち、導入する。
    - **※今回は作業フォルダを作成して、ここにsharpをインストールする。**

```bash
# 作業フォルダの作成
$ mkdir ~/work
# 作業フォルダへの移動
$ cd ~/work
# sharpのインストール(※インストールエラーの場合は、管理者権限で試してみる)
$ npm install sharp
```

### yarnでのインストール
- Node.jsパッケージ管理の`yarn`でのインストールの場合、下記のコマンドをうち、導入する。
    - **※上記のnpmでの手順同様に、作業フォルダを作成して、ここにsharpをインストールする。**

```bash
# 作業フォルダの作成
$ mkdir ~/work
# 作業フォルダへの移動
$ cd ~/work
# sharpのインストール(※インストールエラーの場合、管理者権限で試してみる)
$ yarn add sharp
```

## 手順

### 基本的な画像形式変換の例

#### 画像の準備
- 上記のインストール手順で、「sharpのインストール・作業フォルダの作成」が完了したら、ファイル構造が下記であるか確認する。
- **※yarnを利用した場合、「yarn.lock」も入っている。**

```bash
├─ work
   ├── node_modules
   ├── package-lock.json
```

- 構造の確認後、変換対象として利用する画像を準備して、workフォルダの中に入れる。

```bash
├─ work
   ├── node_modules
   ├── package-lock.json
   ├── penguin.svg
```

#### 変換用JSファイルの作成
- 画像の準備後、先ほどのworkフォルダに任意の名前でJSファイルを作成する。

```bash
# 「basic_convert.js」という名前のJSファイルを作成
$ touch ~/work/basic_convert.js
```

```bash
├─ work
   ├── node_modules
   ├── package-lock.json
   ├── penguin.svg
   ├── basic_convert.js
```

#### JSファイルの記述
- 先ほど作成したJSファイルの中身を下記のようにする。

```js
// sharpの読み込み
const sharp = require("sharp")
 
sharp(process.argv[2])  // 入力画像名に、コマンドの引数を利用
  .toFile(process.argv[3])  // 出力画像名に、コマンドの引数を利用
  .then(function(data) {
    console.log(data)  // 正常処理の場合、出力画像の情報を出す
  })
  .catch(function(err) {
    console.log(err)  // エラーの場合、エラー情報を出す。
  })
```

#### ファイルの実行
- ファイルの記述後、ターミナルへ戻り、下記のコマンドをうち、画像変換処理を行う。

```bash
# 作業フォルダの移動
$ cd ~/work
# 例 : 「node 実行ファイル名 フォルダ内の対象画像ファイル名 作成画像ファイル名」
$ node basic_convert.js penguin.svg penguin.png
```

- コマンド実行後、作成したファイルがフォルダの中に確認できれば完了。

### その他の画像処理メソッドを利用した例
- 「sharp」の様々な画像処理メソッドの中から、下記の基礎的なメソッドの利用例を見ていく。
    - `resize` : 画像のサイズ変換処理
    - `composite` : 複数画像の合成
    - **※その他の膨大な処理メソッド一覧は[こちら](https://github.com/lovell/sharp/tree/master/docs)を確認**

#### JSファイルの記述
- それぞれ「resize・composite」用に、2つのjsファイルを作成する。
  - `resize` : `resize_convert.js`
  - `composite` : `composite_convert.js`
    - `composite_convert.js`内の`gravity`で利用する合成位置リストは、[こちら](https://github.com/lovell/sharp/blob/master/docs/api-composite.md)を確認。

- 作成後、2つのファイルの中身を、下記のようにする。

```js:~/work/resize_convert.js
const sharp = require("sharp")
 
sharp(process.argv[2])
  // 引数の値を、幅として指定。(高さは自動指定)
  .resize(parseInt(process.argv[4]))
  .toFile(process.argv[3])
  .then(function(data) {
    console.log(data)
  })
  .catch(function(err) {
    console.log(err)
  })
```

```js:~/work/composite_convert.js
const sharp = require("sharp")
 
sharp(process.argv[2])
  // inputに、合成画像ファイルを、引数で受け取る。
  // gravityに合成位置を指定。
  .composite([{ input: process.argv[3], gravity: process.argv[5] }])
  .toFile(process.argv[4])
  .then(function(data) {
    console.log(data)
  })
  .catch(function(err) {
    console.log(err)
  })
```

#### ファイルの実行
- 記述後、ターミナルへ戻り、下記のコマンドをうち、画像変換処理(リサイズ・合成)を行う。

```bash
# 作業フォルダへ移動
$ cd ~/work

# リサイズjsファイルの実行
# 例:「node ファイル名 対象画像 作成画像名 幅」
$ node resize_convert.js penguin.png resize_penguin.png 100

# 合成処理jsファイルの実行
# 例:「node ファイル名 合成画像1 合成画像2 作成画像名 合成方向」
$ node composite_convert.js penguin.png word.png composite_penguin.png south
```

- コマンド実行後、作成したファイルがフォルダの中に確認できれば完了。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/dc11715f-b26c-845e-3bb6-0b7ffe9cd677.png)

## まとめ
- 今回は、簡単画像処理ということで、「複雑かつ高度な処理を、容易に扱える」という現代の最大利点に感謝しながら、記事を書く。
- プログラムの醍醐味である「一括処理」と、個人の趣向が組み合わさり、「**動物反転画像**」を大量作成進行中の連休。
- 「反転・合成・切り抜き」という奥深き作業の大量処理が終了したら、次回の調査をすることにしよう。

## 参考
- https://github.com/lovell/sharp  
→公式Gihubです。大変お世話になりました。
- https://kamoqq.info/post/nodejs-image-processor-sharp/  
→こちらを参考にしました。大変お世話になりました。