最速で画像を圧縮するAlfred Workflowを作った

# はじめに
PNGやGIFの圧縮は、ブログ記事やGitHubのPull Requestの実行画像貼り付けとかで割とあります。

自分は[TinyPNG](https://tinypng.com/)や[iLoveIMG](https://www.iloveimg.com/ja) を利用していましたが、プラウザを開きファイルをアップロード・圧縮しダウンロードという手順が毎回面倒でした。
なので、[alfred-imagemin](https://github.com/kawamataryo/alfred-imagemin) という**PNG / JPEG / GIFを手軽に圧縮するAlfred Workflow**を作ってみました。
（GIFでも使えるというのが嬉しいポイントです）

この記事ではalfred-imageminの概要と、仕組みを紹介します。

![May-25-2020 06-44-34.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/e84ddf06-bf74-76d7-5edb-2044ad5b228e.gif)

※ Alfred Workflowは[Alfred](https://www.alfredapp.com/)で[Alfred Powerpack](https://www.alfredapp.com/powerpack/)を導入済みの方のみ使える機能です。[便利なWorkflow](https://qiita.com/ryo2132/items/ef392999d32732fa0455)で作業効率爆上がりなので、未導入の方はぜひこの機会に！


# インストール
以下コマンドでnpmからインストールできます（後述するAlfyで実現しています）。
npmインストールするだけでAlfredがWorkflow認識し、すぐに使えるようになります。


```bash
$ npm i -g alfred-imagemin
```

また、[GitHubのリリース](https://github.com/kawamataryo/alfred-imagemin/releases) から直接`imagemin.workflow`ファイルをダウンロードし、Alfredに取り込むことも可能です。

<img width="1099" alt="スクリーンショット 2020-06-08 7.15.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/80e30870-5d37-1941-75bc-525aa5d20a5b.png">


# 使い方
使い方はこちらの通りです。


**1.** 圧縮したい画像をFinderで選択状態にする（複数選択でもOKです）
**2.** Alfredを開いてimageminと入力しEnterキーを押す
**3.** `optimized_images` フォルダに圧縮済み画像が生成される


最初の実行時には以下アクセス権の確認の項目が出るのでOKを押してください。
その後もう一度実行すれば使えるようになるはずです。
（もしそれで動かなかったらAlfredを再起動してみてください）

![スクリーンショット 2020-05-31 17.03.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/aed6cd7e-23be-0d85-c3ca-258f73fd3d9d.png)
（Finderからの選択ファイルの取得に使います）

# 圧縮率・アウトプットディレクトリの調整
Alfred Workflowの環境変数で、画像ごとの細かい圧縮率の設定やアウトプットするディレクトリ名の変更も可能です。

<img width="1099" alt="スクリーンショット 2020-06-08 7.03.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/09f97bf8-2257-2b5b-1444-df5e2ce7efd9.png">

|名前|デフォルト値|説明|
|---|---|---|
|JPEG_QUALITY | 70 | JPEG圧縮時に使う[imagemin-mozjpeg](https://github.com/imagemin/imagemin-mozjpeg#quality) の圧縮率の設定。0〜100までの数値 |
|PNG_MAX_QUALITY | 0.6 | PNG圧縮時に使う[imagemin-pngquant](https://github.com/imagemin/imagemin-pngquant#quality)のクオリティ（上限）の設定。0〜1までの数値|
|PNG_MIN_QUALITY | 0.5 | PNG圧縮時に使う[imagemin-pngquant](https://github.com/imagemin/imagemin-pngquant#quality)のクオリティ（下限）の設定。0〜1までの数値|
|GIF_OPTIMIZATION_LEVEL | 3 | GIF圧縮時に使う[imagemin-gifsicle](https://github.com/imagemin/imagemin-gifsicle#optimizationlevel)の圧縮レベルの設定。1, 2, 3の3段階|
|OUTPUT_DIR | optimized_images | 圧縮後のファイルを入れる出力先ディレクトリ名 |


# 仕組み

[Alfy](https://github.com/sindresorhus/alfy) というNode.jsベースでAlfred Workflowを作れるツールを使っています。そして画像圧縮自体はnpmの[imagemin](https://github.com/imagemin/imagemin) を利用しています。

https://github.com/sindresorhus/alfy

Alfyを使う利点は以下の通りです。

- Node.jsでWorkflowを作れる
- npmモジュールが使える
- npmに公開し、手軽にinstallできるようになる

何より、Bashスクリプト書かなくてよいというのが最高便利です。
もし需要あればAlfyの使い方も記事にします。

圧縮部分のコードはこんな感じ。
本当にimageminにFinderの選択ファイルを渡しているだけです。

```js
const path = require("path");
const imagemin = require("imagemin");
const imageminMozjpeg = require("imagemin-mozjpeg");
const imageminPngquant = require("imagemin-pngquant");
const imageminGifsicle = require("imagemin-gifsicle");

const argv = process.argv[2];

const files = argv.split("///");

const outDir = path.dirname(files[0]);

const jpegQuality = process.env.JPEG_QUALITY
  ? Number(process.env.JPEG_QUALITY)
  : 70;
const pngMaxQuality = process.env.PNG_MAX_QUALITY
  ? Number(process.env.PNG_MAX_QUALITY)
  : 0.6;
const pngMinQuality = process.env.PNG_MIN_QUALITY
  ? Number(process.env.PNG_MIN_QUALITY)
  : 0.5;
const gifOptimizationLevel = process.env.GIF_OPTIMIZATION_LEVEL
  ? Number(process.env.GIF_OPTIMIZATION_LEVEL)
  : 3;
const outputDir = process.env.OUTPUT_DIR
  ? process.env.OUTPUT_DIR
  : "optimized_images";

// minify images
await imagemin(files, {
  destination: `${outDir.trim()}/${outputDir}`,
  plugins: [
    imageminMozjpeg({ quality: jpegQuality }),
    imageminPngquant({ quality: [pngMinQuality, pngMaxQuality] }),
    imageminGifsicle({ optimizationLevel: gifOptimizationLevel }),
  ],
});

console.log("Processing completed successfully.");
console.log(`Optimized ${files.length} files.`);
```


# 終わりに

以上「最速で画像を圧縮するAlfred Workflowを作った」でした。
不具合などありまたら、気軽にGitHubリポジトリにissueやPull Requestを投げてください。
あと、もし使ってみて良かったらリポジトリにstar :star: を貰えると嬉しいです。泣いて喜びます。

<a href="https://github.com/kawamataryo/alfred-imagemin" target="_blank"><img width="527" alt="スクリーンショット 2020-05-23 21.47.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114396/8a01e3a8-3c61-c45c-fdb7-c9ce1aa8f9dd.png"></a>




# 参考

ツール作った系の記事の書き方として参考にさせていただきました :pray:
（ツールも毎回便利に使わせてもらっています！）

- [プロセスをあいまい検索してkillするツールをGoで作った - Qiita](https://qiita.com/gorilla0513/items/6659ed829e855523ddc6)