53430


**画像URL入力または画像ファイルをアップロード→読み込んだ画像をcanvasに送る→描画開始**  
というコードを作りたいです。  
[現状](https://jsbin.com/wusacahito/6/edit?html,js,output)、画像URLまたはローカルの画像ファイルをアップロードする形で、canvasに画像を描画することはできていますが、

[code]

    $(function () {
    //input url
    $('#url').change(function () {
        var url = $('#url').val();
        var img = new Image();
        img.onload = function () {
            $('#canvas').fadeOut(1);
            var file = $('#file')[0];
            file.value = "";
            $('#canvas').fadeIn(1);
            var cnvsH = 250;
            var cnvsW = img.naturalWidth * cnvsH / img.naturalHeight;
            var canvas = document.querySelector('#canvas');
            canvas.setAttribute('width', cnvsW);
            canvas.setAttribute('height', cnvsH);
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, cnvsW, cnvsH);
        }
        img.src = url;
    });
    //input file
    $('#file').change(function () {
        var file = this.files[0];
        var img = new Image();
        var fr = new FileReader();
        fr.onload = function (e) {
            img.onload = function () {
                $('#canvas').fadeOut(1);
                var url = $('#url')[0];
                url.value = "";
                $('#canvas').fadeIn(1);
                var cnvsH = 250;
                var cnvsW = img.naturalWidth * cnvsH / img.naturalHeight;
                var canvas = $('#canvas');
                canvas.attr('width', cnvsW);
                canvas.attr('height', cnvsH);
                var ctx = canvas[0].getContext('2d');
                ctx.drawImage(img, 0, 0, cnvsW, cnvsH);
            }
            img.src = e.target.result;
        }
        fr.readAsDataURL(file);
      });
    });
    
[/code]

**画像URL入力→描画開始または画像ファイルをアップロード→描画開始**  
になっています。  
なのでinputには画像を読み込むコードのみにし、描画するコードはcanvasのイベントとして一つにまとめたいです。  
どなたか教えていただけないでしょうか。

私が初心者のため理解しにくい説明になっているかと思い、図とコード（もちろん機能しないです）で現状とやりたいことをまとめましたので、よろしければご確認ください。  
[![画像の説明をここに入力](https://i.stack.imgur.com/1nERy.jpg)](https://i.stack.imgur.com/1nERy.jpg)

[![画像の説明をここに入力](https://i.stack.imgur.com/NaadQ.jpg)](https://i.stack.imgur.com/NaadQ.jpg)

[code]

    $(function () {
      //input url
      $('#url').change(function () {
        var file = $('#file')[0];
        file.value = "";
        var url = $('#url').val();
        var img = new Image();
        img.onload = function () {
          //canvasに送りたい
          img = $('#canvas');
        }
      });
      //input file
      $('#file').change(function () {
        var url = $('#url')[0];
        url.value = "";
        var file = this.files[0];
        var img = new Image();
        var fr = new FileReader();
        fr.onload = function (e) {
          img.onload = function () {
            //canvasに送りたい
            img = $('#canvas');
          }
        }
      });
      //canvasに画像が来たら発火
      $('#canvas').change(function(){
        var cnvsH = 500;
        var cnvsW = img.naturalWidth * cnvsH / img.naturalHeight;
        var canvas = document.querySelector('#canvas');
        canvas.setAttribute('width', cnvsW);
        canvas.setAttribute('height', cnvsH);
        var ctx = canvas.getContext('2d');
        ctx.drawImage(img, 0, 0, cnvsW, cnvsH);
      });
      //エンコード？
    });
    
[/code]

canvasに描画した後に加工→保存する機能を実装する予定です。


CC BY-SA 4.0
2019-03-14T08:55:42.290
53427
2019-03-30T11:00:53.000
2019-03-14T09:01:02.963
32275
32275
question
javascript html jquery
画像URL入力または画像ファイルをアップロード→読み込んだ画像をcanvasに送る→描画を開始させたい


「ユーザから見える挙動は想定通り実装できたが、重複しているコードをまとめたい」という理解でよろしいでしょうか。

案のようにcanvasにイベントを起こして画像を伝えることも可能ですが、わざわざcanvasでイベントを起こす必要はありません。共通するコードを関数にして、それぞれのloadイベントで呼べばよいのです。

動くかどうかわかりませんが、コードは以下のようになります。

[code]

    $('#url').change(function() {
      loadImageThenDraw(this.val());
    });
    
    $('#file').change(function() {
      var fr = new FileReader();
      fr.onload = function(e) { loadImageThenDraw(e.target.result); };
      fr.readAsDataURL(this.files[0]);
    });
    
    function loadImageThenDraw(src) {
      var img = new Image();
      img.onload = drawImageOnCanvas;
      img.src = src;
    }
    
    function drawImageOnCanvas(event) {
      $('#url')[0].value = '';
      $('#file')[0].value = '';
      var img = event.target;
      var canvas = $('#canvas');
      canvas.fadeOut(1);
      ...
      ctx.drawImage(img, 0, 0, cnvsW, cnvsH);
    }
    
[/code]


CC BY-SA 4.0
2019-03-14T11:34:39.697
53430
2019-03-14T11:34:39.697
3475
53427
answer


ローカルファイルをFileReaderで読み込み、そのメモリ上の画像をURL化(Blob_URL)してimageなどに表示させることができます。  
それを使用してCanvasオブジェクトにdrawImageすることもできます。

[JQuery
ブラウザで画像ファイルを読み込んでサイズや形式を変換する](https://qiita.com/Urushibara01/items/e3f180ef4d0d03450ab1)  
私が書いた物ですが、参考になりますでしょうか？


CC BY-SA 4.0
2019-03-30T11:00:53.000
53832
2019-03-30T11:00:53.000
32723
53427
answer