ローカルファイルの画像をコンテキストメニューからMarkdownリンクに変換する

[Typora](https://typora.io/#)というMarkdownエディターに出会ってからドキュメントはmarkdownで書くようになりました。
Typoraではローカルの画像をエディタ上に貼り付けてそのまま表示することができます。

■こんな感じに↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/3f895658-23cc-8bda-0747-8b107969586e.png)

ローカルにある画像を`![名前](画像リンク)`で指定すればTyporaでは表示されます。
手順としては画像をTyporaにD&Dすることでいい感じに上のような表示になります。

ただ、Windowsのコンテキストメニューから画像を`![名前](画像リンク)`の形式にしてくれないかと考えました。
今回はコンテキストメニューへのリンク追加と、上のフォーマットに変換するプログラムを用意して実現します。

# コンテキストメニューへの追加
そもそもコンテキストメニューってどんなやつかというのは下のやつです。
画像を右クリックしたときに出てくるメニューですね。ここはユーザーによって項目が異なります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/37cf899c-e260-7307-3f03-41fda18746c7.png)

ここに項目を追加します。
## レジストリエディタに設定追加
**コンピュータ > HKEY_CLASSES_ROOT > * > shell**を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/b86d8aa1-a275-1f5b-aff4-b47ef5449435.png)

**キーの追加：ここは自由に名前をつける(今回はMarkdownリンク(&Q))**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/538bcff2-751f-a436-caa0-33c3035a220e.png)

この時点でコンテキストメニューに上の内容が表示されるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/3738bf08-35f3-72ea-c435-7a5d19774603.png)

**キーの追加：command**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/920c3030-964b-8dff-168e-128301c1b25e.png)

**項目の編集："プログラム名(後述)のexeのパス" "%1"**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/419bbde8-1c7a-4968-0ad5-dea1b5bcb8fd.png)


とりあえずこの時点で一度レジストリの設定は終わりです。
次に変換用のプログラムの方を用意します。

## Markdownリンク用の変換ツールの用意
ここは好きな言語で用意すれば良いと思いますが、サンプルとしてC#で今回作りました。
ポイントは、引数としてコンテキストメニューで押されたファイルのパスをmainメソッドのargs[]で受け取っているので
このファイルパスに対してゴニョゴニョして最終的にmarkdown形式の文字列としてクリップボードにコピーするイメージです。
C#ベースのコンソールアプリケーションですがウィンドウを表面に出したくないので、出力の種類は「Windows アプリケーション」にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/d54bed3e-4d82-5651-5894-d32d5c006504.png)


```C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Collections;
using System.Drawing.Imaging;

namespace filepathMarkdownConvert
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            string markdownLink = System.String.Empty;
            try
            {
                string srcPath = args[0].ToString();
                string fileName = Path.GetFileName(srcPath);

                string format = GetImageFormat(Path.GetExtension(srcPath));
                markdownLink = fileName + "](" + srcPath + ")";
                // 画像形式とそれ以外でフォーマットを変える
                markdownLink = (format != null) ? "![" + markdownLink : "[" + markdownLink;
                Clipboard.SetDataObject(markdownLink, true);
            }
            catch
            {
                // not
            }
        }

        /// <summary>
        /// イメージのファイルフォーマットを拡張子から判断し取得する [C#]:humming bird http://yas-hummingbird.blogspot.com/2009/02/c_06.html
        /// </summary>
        /// <param name="ext"></param>
        /// <returns></returns>
        public static string GetImageFormat(string ext)
        {
            foreach (ImageCodecInfo ici in ImageCodecInfo.GetImageDecoders())
            {
                foreach (string s in GetFileNameExtensions(ici))
                {
                    if (s.ToUpper() == ext.ToUpper())
                    {
                        return ici.FormatDescription;
                    }
                }
            }
            return null;
        }

        /// <summary>
        /// イメージのファイルフォーマットを拡張子から判断し取得する [C#]:humming bird http://yas-hummingbird.blogspot.com/2009/02/c_06.html
        /// </summary>
        /// <param name="ici"></param>
        /// <returns></returns>
        public static IEnumerable GetFileNameExtensions(ImageCodecInfo ici)
        {
            foreach (string s in ici.FilenameExtension.Split(';'))
            {
                yield return s.Substring(s.IndexOf('.'));
            }
        }
    }
}
```

**作成してビルドしたアプリケーションを任意の場所に配置してそのファイルパスをコピーしておきます**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/66030096-3f21-7c35-ecae-82423a6ffb62.png)

**レジストリエディタの変換ツールのフルパスの部分にプログラムのパスを代入します**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/72ec508c-c0e8-c8a5-0dc5-0557a114abeb.png)

これで準備OKです

## 結果
![34b58d1b6246270be536902682588eef.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263877/2a76e2f5-3a81-2ba2-52b7-d957a3cfaa65.gif)
わかりにくいですが、コンテキストメニューから追加したMarkdownリンクを選択すると
上で作成した変換ツールがバックグラウンドで起動してクリップボードに内容をコピーしています。

とりあえずこれでTyporaに画像をD&Dしなくても良くなりました。個人的には満足です。
※もしかしたらもっといい方法があるかもしれないです

コンテキストメニューに任意の項目を追加してアプリ実行ができるというのは収穫でした。


## 参考
[右クリックメニューにアイテムを追加する \- Windows 10](https://www.billionwallet.com/goods/windows10/win10_mouse_rightclick.html)
[イメージのファイルフォーマットを拡張子から判断し取得する \[C\#\]:humming bird](http://yas-hummingbird.blogspot.com/2009/02/c_06.html)