52
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

JavaScriptでクリップボードの画像を取得する

初めに

クリップボードに格納されている画像をJavaScriptから取り出す機会があったのでメモ。
(例によってニッチなネタです。)

制約

クリップボードの値を取り出すには、ユーザのアクション(ペースト)が必須です。 セキュリティの関係で好き放題アクセスできないようになっているようです。この壁を乗り越えるにはFlashを使うなどの手法があるようですが、この記事ではそれらには触れません。

したがって、ここで紹介する方法の応用場所は相当限られると思います。
たとえば、Qiitaの編集画面でちょっとした画面キャプチャを添付したいときに、いちいちファイルを介さずに添付できるとか・・・どうかなぁ・・・?微妙?

まぁ、こんなアイデアもあるよってことで・・・

サンプル

printscreen(macならctrl + shift + cmd+ 3)で画面キャプチャを取った後、上記ページの「paste image here」という部分でペーストを実行してください。JavaScriptで画像を取得した後、下部のimgタグとtextareaに結果が反映されます。

サンプル画面

手順

ブラウザによって手順が若干異なりますが、基本的な発想は同じでです。
contenteditableな要素に画像を張り付けてそれを取ってくるという方法です。

Firefox, IE, Safariの場合

contenteditableな要素に画像を張り付けると、エレメント内にimgタグが挿入されるので、簡単に取得できます。

<div contenteditable="true" width="50px" height="50px">
paste image here
</div>

<img id="outputImage" border="1" width="50%">
<textarea id="outputText"></textarea>

<script>
var element =  document.querySelector("[contenteditable]");
element.addEventListener("input", function(e){
    // 仮のエレメントを作り、張り付けた内容にimgタグがあるか探す
    var temp = document.createElement("div");
    temp.innerHTML = this.innerHTML;
    var pastedImage = temp.querySelector("img");

    // イメージタグがあればsrc属性からbase64が得られるので
    // あとは煮るなり焼くなり
    if (pastedImage) {
        var base64 = pastedImage.src;

        document.querySelector("#outputImage").src = base64;
        document.querySelector("#outputText").textContent = base64;
    }

    // contenteditableの内容は戻しておく
    this.innerHTML = "paste image here";
})

</script>

Chromeの場合

Chromeの場合は画像を張り付けても画像は挿入されません。しかし、pasteイベントからファイルオブジェクトして画像を取り出すことができます。若干面倒です。

<div contenteditable="true" width="50px" height="50px">
paste image here
</div>

<img id="outputImage" border="1" width="50%">
<textarea id="outputText"></textarea>

<script>
var element =  document.querySelector("[contenteditable]");
element.addEventListener("paste", function(e){
    // 画像の場合
    // e.clipboardData.types.length == 0
    // かつ
    // e.clipboardData.types[0] == "Files"
    // となっているので、それ以外を弾く
    if (!e.clipboardData 
            || !e.clipboardData.types
            || (e.clipboardData.types.length != 1)
            || (e.clipboardData.types[0] != "Files")) {
            return true;
    }

    // ファイルとして得る
    // (なぜかgetAsStringでは上手くいかなかった)
    var imageFile = e.clipboardData.items[0].getAsFile();

    // FileReaderで読み込む
    var fr = new FileReader();
    fr.onload = function(e) {
        // onload内ではe.target.resultにbase64が入っているのであとは煮るなり焼くなり
        var base64 = e.target.result;
        document.querySelector("#outputImage").src = base64;
        document.querySelector("#outputText").textContent = base64;
    };
    fr.readAsDataURL(imageFile);

    // 画像以外がペーストされたときのために、元に戻しておく
    this.innerHTML = "paste image here";
});
</script>
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
52
Help us understand the problem. What are the problem?