プロジェクト

全般

プロフィール

20210214 » 履歴 » バージョン 5

健二 酒井, 2021/02/14 20:59
スクリプトを書いたので追加

1 1 健二 酒井
# 20210214
2 1 健二 酒井
3 1 健二 酒井
実に半年ぶりぐらい。大体こんなことをやろうとしている
4 1 健二 酒井
5 1 健二 酒井
## 出発
6 1 健二 酒井
7 1 健二 酒井
Snipping ToolsはCtrl + C でキャプチャした画像をクリップボードに入れられる。
8 1 健二 酒井
いちいちファイル保存を経由して、MarkdownEditorに貼るのは面倒なので
9 1 健二 酒井
クリップボードに保管した画像をDATA URIスキームで貼り付けたいというひと手間省くためだけの願望を実現しようと色々調べてみた結果。
10 1 健二 酒井
11 1 健二 酒井
以下、記事のお品書き
12 1 健二 酒井
13 1 健二 酒井
1. Webとクリップボード 
14 1 健二 酒井
1. PowerShellとクリップボード
15 1 健二 酒井
1. .NETのImageのbase64エンコーディング
16 4 健二 酒井
1. PowerShellスクリプト
17 1 健二 酒井
18 1 健二 酒井
### Webでのクリップボード
19 1 健二 酒井
20 1 健二 酒井
願望からやらなきゃいけないことは
21 1 健二 酒井
22 1 健二 酒井
- Clipboardのデータを読む
23 1 健二 酒井
- 生データをbase64エンコードする
24 1 健二 酒井
25 1 健二 酒井
主に前者についてのお話。
26 1 健二 酒井
今まで使っていたexecCommandはいつ削除されてもおかしくないらしい。なんということ。
27 1 健二 酒井
28 1 健二 酒井
という訳でクリップボードの正しい扱い方について情報収集していった。代替となりそうなW3C Clipboard APIだけどまだ草案段階でMDNのドキュメントも反映されきってないという素敵な状況。
29 1 健二 酒井
まだ使えないなぁということで色々ぐぐってたら出てきたのがpaste.js: https://github.com/layerssss/paste.js 先人は偉大。
30 1 健二 酒井
ソース眺めた感じ、Navigator.clipboardオブジェクトを基本的に使いつつ、Firefox対応の処理を入れている感じ。よさげ。pasteImageなるイベントも実装してくれてるし。
31 1 健二 酒井
32 1 健二 酒井
### PowerShellとクリップボード
33 1 健二 酒井
34 1 健二 酒井
さて、paste.jsで実装しようかなと思ったんだけど、「クリップボードの画像をbase64エンコードする」ってブラウザでやるべきことか?とか疑問が沸いてきたため、例えばPowerShellとか使う方法を考えてみる。
35 1 健二 酒井
36 1 健二 酒井
1. クリップボードから画像を読む
37 1 健二 酒井
1. 読んだ画像をbase64エンコードする
38 1 健二 酒井
1. base64文字列をクリップボードに入れる
39 1 健二 酒井
40 1 健二 酒井
とかそんな処理を書けばいいのかなと。ブラウザでやるとセキュリティとかメンドウクサイ。
41 1 健二 酒井
とりあえず、使えそうなコマンドレットは以下二つ。
42 1 健二 酒井
43 1 健二 酒井
- Get-Clipboard
44 1 健二 酒井
- Set-Clipboard
45 1 健二 酒井
46 1 健二 酒井
Set-Clipboardは今回見ない。
47 1 健二 酒井
48 1 健二 酒井
リファレンス( https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-clipboard?view=powershell-5.1 )によると-Formatオプションでテキストだの画像だの音声だのと指定できるらしい、が、PowerShell 7ではこのオプション削除されているらしいのは注意。Windows想定だからPowerShell 5.1で良いや。
49 1 健二 酒井
50 1 健二 酒井
コマンド結果:
51 3 健二 酒井
52 1 健二 酒井
```
53 3 健二 酒井
PS $ Get-Clipboard -Format Image  |sv image
54 3 健二 酒井
PS $ $image.GetType()
55 1 健二 酒井
56 1 健二 酒井
IsPublic IsSerial Name                                     BaseType
57 1 健二 酒井
-------- -------- ----                                     --------
58 1 健二 酒井
True     True     Bitmap                                   System.Drawing.Image
59 1 健二 酒井
```
60 1 健二 酒井
61 1 健二 酒井
なんかBitmapクラスとかいうよくわからんのが出来たので調べよう。後参考( https://www.haruru29.net/blog/how-to-do-clipboard-operations-using-powershell/ )によるとリソースの開放とか気を付けたほうが良いみたい。まぁそうか。
62 1 健二 酒井
63 3 健二 酒井
## .NETのImageのbase64エンコーディング
64 1 健二 酒井
65 1 健二 酒井
なんか以前、System.Text.Encodingクラスとかからテキストをバイト列にしたことはあったな。そう確かPowerShell 5.1 でUTF-8で保存すると、ついてしまうBOMを外すためにやった。今回は画像なのでちょっと違うなぁ。
66 1 健二 酒井
結局のところバイトストリームを得られればいいんじゃないかな。
67 1 健二 酒井
ImageクラスのSaveMemoryStream(Stream,ImageFormat)でMemoryStreamに保存、バイト列化してConvertクラスでbase64エンコーディングとかでいけそうかなぁ。
68 1 健二 酒井
69 4 健二 酒井
70 4 健二 酒井
## PowerShellスクリプト
71 4 健二 酒井
72 4 健二 酒井
というわけでできた。以下のように選べるようにしてみた。
73 4 健二 酒井
74 4 健二 酒井
- 出力先:パイプライン・クリップボード
75 4 健二 酒井
- 出力形式:base64文字列・Markdownの画像・DataURIスキーム
76 4 健二 酒井
77 4 健二 酒井
78 4 健二 酒井
```PowerShell
79 4 健二 酒井
80 4 健二 酒井
function ClipImageToBase64() {
81 4 健二 酒井
    Param(
82 4 健二 酒井
        [string]
83 4 健二 酒井
        [ValidateSet('base64', 'Markdown', 'dataURI')]
84 4 健二 酒井
        $Format = 'base64',
85 4 健二 酒井
        [switch]
86 4 健二 酒井
        $Clip
87 4 健二 酒井
    )   
88 4 健二 酒井
    $image = Get-Clipboard -Format Image;
89 4 健二 酒井
    $ms = New-Object -TypeName System.IO.MemoryStream;
90 4 健二 酒井
    $image.Save($ms, [System.Drawing.Imaging.ImageFormat]::Png);
91 4 健二 酒井
    
92 4 健二 酒井
    $encoded = [System.Convert]::ToBase64String($ms.GetBuffer());
93 4 健二 酒井
    $image.Dispose();
94 4 健二 酒井
    $ms.Dispose();
95 4 健二 酒井
96 4 健二 酒井
    switch ($format) {
97 4 健二 酒井
        'base64' {
98 4 健二 酒井
            $dataUri = $encoded;
99 4 健二 酒井
        }
100 4 健二 酒井
        'dataURI' {
101 4 健二 酒井
            $dataUri = "data:image/png;base64," + $encoded;
102 4 健二 酒井
        }
103 4 健二 酒井
        'Markdown' {
104 4 健二 酒井
            $dataUri = "![](data:image/png;base64," + $encoded + ")";
105 4 健二 酒井
        }
106 4 健二 酒井
    }
107 4 健二 酒井
108 4 健二 酒井
    if($Clip) {
109 4 健二 酒井
        $dataUri | Set-Clipboard
110 4 健二 酒井
    }
111 4 健二 酒井
}
112 4 健二 酒井
113 4 健二 酒井
```
114 4 健二 酒井
115 1 健二 酒井
## 参考
116 1 健二 酒井
117 1 健二 酒井
- https://developer.mozilla.org/ja/docs/Web/API/Document/execCommand
118 1 健二 酒井
- https://qiita.com/tatesuke/items/00de1c6be89bad2a6a72
119 1 健二 酒井
- https://qiita.com/chelproc/items/9e0328e5d413afb52d0c
120 1 健二 酒井
- https://github.com/layerssss/paste.js
121 1 健二 酒井
- https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-clipboard?view=powershell-5.1
122 1 健二 酒井
- https://win.just4fun.biz/?PowerShell/PowerShell%E3%81%A7Base64%E3%81%AE%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A8%E3%83%87%E3%82%B3%E3%83%BC%E3%83%89
123 1 健二 酒井
- https://www.haruru29.net/blog/how-to-do-clipboard-operations-using-powershell/
124 2 健二 酒井
- https://blog.beaglesoft.net/entry/2011/02/14/bitmap%25e3%2583%2595%25e3%2582%25a1%25e3%2582%25a4%25e3%2583%25ab%25e3%2582%2592base64%25e3%2581%25a7%25e3%2582%25a8%25e3%2583%25b3%25e3%2582%25b3%25e3%2583%25bc%25e3%2583%2587%25e3%2582%25a3%25e3%2583%25