※ 2018-12 に記述したメモです。Gist にアップロードした時点と比べて内容が古い可能性があります
Windows でコピーした画像を Bes64 形式のテキストで VcXsrv のクリップボードに渡す のための実験のメモ. なので特に結論めいたものはない.
とりあえず linux の場合は、$ xclip -selection clipboard -t image/jpeg -o > chk.jpg
で、
Windows の場合は Get-Clipboard
でどうにかなりそう.
なのだが、VxXsrv だと Windows でコピーした画像に Linux 側からはアクセスできないぽい. Windows 側でテキストとしてコピーしなおすとかかねぇ. その場合 base64 とかいる?いるよねぇ.
参考
- scripting - Copy image from clipboard to file - Unix & Linux Stack Exchange scripting x11 images clipboard
- cmd - How can you get the clipboard contents with a Windows command? - Stack Overflow windows cmd clipboard copy-paste
- Get-Clipboard
上記の Get-Clipboard
を使うことで対応できるのだが、いくつかはまり所があったのでメモ.
まず、PS> Get-Clipboard -Format Image
で取得できるのは、
System.Drawing.Image
型なのでそのままでは(PowerShell のオブジェクトとしては)パイプ等にわたせない、
と思う.
この型には Save
メソッドがあるのでそれを使うことでファイルに保存できるのだが、
このメソッドは絶対パスでないと受け付けないもよう.
相対パスを指定するとエラーが発生する.
"2" 個の引数を指定して "Save" を呼び出し中に例外が発生しました: "GDI+ で汎用エラーが発生しました。"
最終的には以下のようにするとうまくいく.
PS> (Get-Clipboard -Format Image).Save("c:\\tmp\\test.png", [System.Drawing.Imaging.ImageFormat]::Jpeg)
あとは base64 でエンコードできればよいのだが.ストリームでどうにかなる?
参考
- Image Class (System.Drawing) | Microsoft Docs
- Image.Save Method (System.Drawing) | Microsoft Docs # Save(String, ImageFormat)
ちょっと試してみたのだが、 以下でいけそうな感じ(まだ文字エンコードがうまくあわない).
$ms=[System.IO.MemoryStream]::new()
(Get-Clipboard -Format Image).Save($ms, [System.Drawing.Imaging.ImageFormat]::Jpeg)
[System.Convert]::ToBase64String($ms.ToArray()) > test.b64
Powershell 側エンコードをいじるのはめんどそうなので、 linux 側で調整
$ cat test.b64 | iconv -f UTF-16 -t UTF-8 | base64 -d -i > test_decode.jpg
これでうまくいく感じかな.
ただし、base64
で -i
を指定しないとだめなのがちょっとおもしろくはない
(まだ BOM が残っている?)
と、思ったのだがk改行が CRLF(CR/LF) だったのが原因だったもよう.
以下のように変換して対応できた.
てか、その辺は base64
でてきとうに捌いてほしかったり.
$ cat test.b64 | iconv -f UTF-16 -t UTF-8 | tr -d \\r | base64 -d > test_decode.jpg
で、ここまで長々と書いたが、 この辺の変換はファイルではなく以下のようにクリップボード経由で処理すればもちっと簡単になる.
Windows でコピーした画像を Bes64 形式のテキストで VcXsrv のクリップボードに渡す
License: CC0 1.0 http://creativecommons.org/publicdomain/zero/1.0/deed.ja