質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • JavaScript

    17541questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    7111questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • canvas

    272questions

    HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

Canvasで画像を重ね合わせて描画した要素をそのまま画像として生成したい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 2,151

sika

score 34

こちらのページを参考にhtml5のFile APIを使ってドラッグ&ドロップし、そこに放り込まれた画像をベース画像とし、重ねレイヤーとしての画像を1枚に合わせてcanvasで描画することまではできましたが、
こちらで描画されたcanvas要素をそのまま画像ファイルとしてcaptureImage要素内に出力したいのですが、画像としての生成手順がわかりません。

下記のコードの修正点のご教授宜しくお願い致します。

<div id="dropZone">画像ファイルを<br>ドロップ</div>
<div id="captureImage">
<canvas id="imageCanvas"></canvas>
</div>
#dropZone{
display: block;
border: 2px dashed #bbb;
border-radius: 5px;
color: #bbb;
padding: 25px;
text-align: center;
margin: 10px auto 5px;
font-size: 12px;
-khtml-user-drag: element;
}

#captureImage{
width: 500px;
height: 500px;
}
    function handleFileSlice(evt) {

        evt.stopPropagation();
        evt.preventDefault();
        var files = evt.dataTransfer.files;
        var output = [];
        for (var i = 0, f; f = files[i]; i++) {

            //ファイルの形式を確認
            if (!f.type.match('image.*')) {
                alert("このファイルは画像ファイルではありません");
                continue;
            }

            var file = f;

            //重ね合わせる画像パスを配列に格納
            var fileArray = [URL.createObjectURL(file), "icon.png"];
            var xywh = [{x: 0, y: 0, w: 500, h: 500}, {x: 10, y: 10, w: 100, h: 100}];
            var numFiles = fileArray.length;
            var loadedCount = 0;
            var imageObjectArray = [];


            var canvas = document.getElementById('imageCanvas');
            var ctx = canvas.getContext('2d');


        function loadImages(){
                var imgObj = new Image();
                imgObj.addEventListener('load',
                    function(){
                        loadedCount++;
                        imageObjectArray.push(imgObj);
                        if(numFiles === loadedCount){
                            drawImage();
                        }else{
                            loadImages();
                        }
                    },
                    false
                );

                imgObj.src = fileArray[imageObjectArray.length];
                $("#captureImage").append(imgObj[1]);
            }
            function drawImage(){
                canvas.width = 500;
                canvas.height = 500;
                for(var i in imageObjectArray){
                    ctx.drawImage(imageObjectArray[i], xywh[i]['x'], xywh[i]['y'], xywh[i]['w'], xywh[i]['h']);
                    imageObjectArray[i] = null;
                }
            }
            loadImages();            
        };


    };

    //画像ファイルのドラッグ&ドロップ設定
    function handleDragOver(evt) {
        evt.stopPropagation();
        evt.preventDefault();
        evt.dataTransfer.dropEffect = 'copy';
    };
    var resizeZone = document.getElementById('dropZone');
    resizeZone.addEventListener('dragover', handleDragOver, false);
    resizeZone.addEventListener('drop', handleFileSlice, false);        
    resizeZone.addEventListener('dragenter', handleDragOver, false);

※できれば生成される画像のファイル名も元のドロップファイル名を引き継いで出力できれば理想です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • turbgraphics200

    2017/01/19 19:39

    ファイル名の引継ぎとはダウンロードさせるのが目的なのでしょうか?

    キャンセル

  • sika

    2017/01/19 19:42

    はい、そうです。用途としては元画像にアイコンを付けて再ダウンロードという物になりますので、可能ならば元ファイル名をそのまま引き継ぐことができれば理想です。

    キャンセル

回答 1

checkベストアンサー

+1

<canvas>にtoDataURL()でURL.createObjectURLと同等のことができます。また、toBlob()でも同様のことができます。toDataURL()との違いは、toDataURL()はbase64を使用したURLとなるため、メモリ使用量が大きくなります。ただ取得は同期で取得することが可能です。toBlob()はBlobで取得するためバイナリーデータのままで扱うことができますが、取得は非同期となります。また、toBlob()はSafariがまだ未対応です。
それと、ファイル名ですが、<a>のdownload属性に元のファイル名を設定すれば、ダウンロードするときにそのファイル名が使用されます。

// toBloB()を使用した場合
if(cnv.toBlob) {
    cnv.toBlob(function(blob) {
        var dlAnchor = document.createElement('a');
        dlAnchor.download = file.name;
        var dlImg = new Image();
        dlAnchor.href = dlImg.src = URL.createObjectURL(blob);
        dlAnchor.appendChild(dlImg);
        document.body.appendChild(dlAnchor);
    }, function(err) {console.log(err)});
}

// toDataURL()を使用した場合
var url = cnv.toDataURL();
var dlAnchor2 = document.createElement('a');
dlAnchor2.download = file.name;
var dlImg2 = new Image();
dlAnchor2.href = dlImg2.src = url;
dlAnchor2.appendChild(dlImg2);
document.body.appendChild(dlAnchor2);

デモ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/01/19 22:55

    いただいたデモコードを参考にaタグとしての画像生成に成功しました!
    toDataURL()とtoBlob()についての特徴の違いや、今回初めてaタグに"download"属性というものがあることを知りました。
    心より感謝致します。ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.33%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • JavaScript

    17541questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    7111questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • canvas

    272questions

    HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。