【JavaScript】CANVASの画像をダウンロード

<!DOCTYPE>
<html>
<head>
<meta charset="UTF-8">
    <title>CANVASによる画像縮小表示とダウンロード</title>
</head>
<body>
<div id="contents" style="margin:20px; border-top:solid 1px #000;">
  <h3>CANVASによる画像縮小表示とダウンロード</h3>
  <input id="inputFile" name="photo" type="file" accept="image/*" capture><br>
  <div><span id="msg"></span></div>
</div>
<p id="downloadButton"><a href="img.jpg">download</a></p>
<a download id="sample-download">ダウンロード</a>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script>
    // 同一パスに画像ファイルを置いておく
    $(function() { 
        // downloadButtonリンクをクリックした場合
        $('#downloadButton a').on('click', function(e){
             
            var hrefPath = $(this).attr('href');       
            var fileName = $(this).attr('href').replace(/\\/g,'/').replace( /.*\//, '' );
             
            $target = $(e.target);
            $target.attr({
                download: fileName,
                href: hrefPath
            });
        });
    });

  // 変更したら
  $('input[name=photo]').change(function(e) {
    // ファイル情報取得
    var file = e.target.files[0];
    var name = file.name;           // ファイル名
    var size = file.size;           // ファイルサイズ
    var type = file.type;           // ファイル形式
    var modify = file.lastModifiedDate;       // ファイル更新日
    
    // ファイル更新日の編集
    var y = modify.getFullYear();  
    var m = modify.getMonth() + 1;
    var d = modify.getDate();
    var w = modify.getDay();

    // 曜日の表記を文字列の配列で指定
    var wNames = ['日', '月', '火', '水', '木', '金', '土'];
    
    // 「月」と「日」で1桁だったときに頭に 0 をつける
    if (m < 10) {
      m = '0' + m;
    }
    if (d < 10) {
      d = '0' + d;
    }
    
    var modifyWork = y + '年' + m + '月' + d + '日 (' + wNames[w] + ')';
    // フォーマットを整形してコンソールに出力
    console.log(modifyWork);
    
    // ファイル情報編集
    var str = "名前:" + name + "<br>";
    str += "サイズ:" + size + "<br>";
    str += "タイプ:" + type + "<br>";
    str += "最終修正日時:" + modifyWork + "<br>";
      
    // ファイル情報を表示
    document.getElementById("msg").innerHTML = str;
    
    // ファイル形式がimageに一致する場合
    if (file.type.match(/image.*/)) {
      // canvasオブジェクトを作成
      var canvas = document.createElement("canvas");
      var ctx = canvas.getContext('2d');
      var image = new Image();
      var size = 1200;
      // 
      canvas.width = canvas.height = 0;
      image.src = URL.createObjectURL(file);
      image.onload = function() {
        var w = size, h = image.height * (size/image.width);
        canvas.width = w;
        canvas.height = h;
        // drawImageでcanvas上に画像を表示
        // drawImageの説明はhttp://www.html5.jp/canvas/ref/method/drawImage.html
        ctx.drawImage(image, 0, 0, w, h);

        var img = document.createElement('img');
        // 画像ファイル出力(出力時のコンテンツタイプを指定)
        img.src = canvas.toDataURL(file.type);

        var head = 'data:' + file.type + ';base64,';
        
        // ファイルサイズを
        var imgFileSize = Math.round((img.src.length - head.length)*3/4);
        
        // 変換前後のサイズを編集しcontentsに追加  
        $('#contents').append("<div><span>" + 
            "元画像サイズ" + (file.size/1024).toFixed(1) + "kb" + " => " + 
            "変換後サイズ" + (imgFileSize/1024).toFixed(1) + "kb" + "</span></div>")
        
        // サイズ縮小した画像情報をブラウザに表示
        $("#contents").append(img);
        
        // サイズ縮小した画像情報をhrefに設定
        document.getElementById("sample-download").href = img.src; 
      }
    }
  });

</script>
</body>
</html>

【JavaScript】改訂新版JavaScript本格入門で勉強

以下にサンプルもあるので勉強してみる

www.wings.msn.to

Chapter 1:イントロダクション
1.1 JavaScriptとは?
 1.1.1 JavaScriptの歴史
 1.1.2 復権のきっかけはAjax、そしてHTML5
 1.1.3 マイナスイメージの誤解
 1.1.4 言語としての4つの特徴
1.2 次世代JavaScript「ECMAScript 2015」とは?
 1.2.1 ブラウザーの対応状況
1.3 ブラウザー付属の開発者ツール
 1.3.1 開発者ツールを起動する
 1.3.2 HTML/CSSのソースを確認する - [Elements]タブ -
 1.3.3 通信状況をトレースする - [Network]タブ -
 1.3.4 スクリプトをデバッグする - [Sources]タブ -
 1.3.5 ストレージ/クッキーの内容を確認する - [Application]タブ -
 1.3.6 ログ確認/オブジェクト操作などの万能ツール - [Console]タブ -
Chapter 2:基本的な書き方を身につける
2.1 JavaScriptの基本的な記法
 2.1.1 JavaScriptで「こんにちは、世界!」
 2.1.2 JavaScriptをHTMLファイルに組み込む - <Script>要素 -
 2.1.3 文(Statement)のルール
 2.1.4 コメントを挿入する
2.2 変数/定数
 2.2.1 変数を宣言する
 2.2.2 識別子の命名規則
 2.2.3 定数を宣言する
2.3 データ型
 2.3.1 JavaScriptの主なデータ型
 2.3.2 リテラル
2.4 演算子
 2.4.1 算術演算子
 2.4.2 代入演算子
 2.4.3 比較演算子
 2.4.4 論理演算子
 2.4.5 ビット演算子
 2.4.6 その他の演算子
 2.4.7 演算子の優先順位と結合測
2.5 制御構文
 2.5.1 条件によって処理を分岐する - if命令 -
 2.5.2 式の値によって処理を分岐する - switch命令 -
 2.5.3 条件氏によってループを制御する - while/do...while命令 -
 2.5.4 無限ループ
 2.5.5 指定回数だけループを処理する - for命令 -
 2.5.6 連想配列の要素を順に処理する - for...in命令 -
 2.5.7 配列などを順に処理する - for...of命令 -
 2.5.8 ループを途中でスキップする/中断する - break/continue命令 -
 2.5.9 ●例外を処理する - try...catch...finally命令 -
         → 仕事で例外処理って書いてないな。
 2.5.10 ●JavaScriptの危険な構文を禁止する - Strictモード -
Chapter 3:基本データを操作する - 組み込みオブジェクト -
3.1 オブジェクトとは
 3.1.1 オブジェクト=プロパティ+メソッド
 3.1.2 オブジェクトを利用するための準備 - new演算子 -
 3.1.3 静的プロパティ/静的メソッド
 3.1.4 組み込みオブジェクトとは
3.2 基本データを扱うためのオブジェクト
 3.2.1 文字列を操作する - Stringオブジェクト -
 3.2.2 数値を操作する - Numberオブジェクト -
 3.2.3 シンボルを作成する - Symbolオブジェクト -
 3.2.4 基本的な数学演算を実行する - Mathオブジェクト -
3.3 値の集合を管理/操作する - Array/Map/Setオブジェクト -
 3.3.1 ●配列を操作する - Arrayオブジェクト -
 3.3.2 p連想配列を操作する - Mapオブジェクト -
 3.3.3 重複しない値の集合を操作する - Setオブジェクト -
3.4 日付/時刻データを操作する - Dateオブジェクト -
 3.4.1 Dateオブジェクトを生成する
 3.4.2 日付/時刻値を加算/減算する
 3.4.3 日付/時刻の差分を求める
3.5 正規表現で文字を自在に操作する - RegExpオブジェクト -
 3.5.1 JavaScriptで利用可能な正規表現
 3.5.2 RegExpオブジェクトをを生成する方法
 3.5.3 正規表現による検索の基本
 3.5.4 正規表現のオプションでマッチング時の挙動を制御する
 3.5.5 matchメソッドとexecメソッドの挙動の違い
 3.5.6 マッチングの成否を検証する
 3.5.7 正規表現で文字列を置き換える
 3.5.8 正規表現で文字列を分割する
3.6 すべてのオブジェクトのひな形 - Objectオブジェクト -
 3.6.1 オブジェクトを基本型に変換する - toString/valueOfメソッド -
 3.6.2 オブジェクトをマージする - assignメソッド -
 3.6.3 オブジェクトを生成する - createメソッド -
 3.6.4 不変オブジェクトを定義する
3.7 JavaScriptプログラムでよく利用する機能を提供する - Globalオブジェクト -
 3.7.1 Numberオブジェクトに移動したメソッド
 3.7.2 クエリ情報をエスケープ処理する - encodeURI/encodeURIComponent関数 -
 3.7.3 動的に生成したスクリプトを実行する - eval関数 -
Chapter 4:くり返し利用するコードを1箇所にまとめる - 関数 -
4.1 関数とは
 4.1.1 function命令で定義する
 4.1.2 Functionコンストラクター経由で定義する
 4.1.3 関数リテラル表現で定義する
 4.1.4 アロー関数で定義する
4.2 関数定義における4つの注意点
 4.2.1 return命令の直後で改行しない
 4.2.2 関数はデータ型の一種
 4.2.3 function命令は静的な構造を宣言する
 4.2.4 関数リテラル/Functionコンストラクターは実行時に評価される
4.3 変数はどの場所から参照できるか - スコープ -
 4.3.1 グローバル変数とローカル変数の違い
 4.3.2 変数宣言にvar命令が必須な理由
 4.3.3 ローカル変数の有効範囲はどこまで?
 4.3.4 仮引数のスコープ - 基本型と参照型の違いに注意する -
 4.3.5 ブロックレベルのスコープは存在しない(ES2015以前)
 4.3.6 ブロックスコープに対応したlet命令
 4.3.7 関数リテラル/Functionコンストラクターにおけるスコープの違い
4.4 引数のさまざまな記法
 4.4.1 JavaScriptは引数の数をチェックしない
 4.4.2 可変長引数の関数を定義する
 4.4.3 明示的に宣言された引数と可変長引数を混在させる
 4.4.4 名前付き引数でコードを読みやすくする
4.5 ES2015における引数の記法
 4.5.1 引数のデフォルト値
 4.5.2 可変長引数の関数を定義する
 4.5.3 「...」演算子による引数の展開
 4.5.4 名前付き引数でコードを読みやすくする
4.6 関数呼び出しと戻り値
 4.6.1 複数の戻り値を個別の変数に代入する
 4.6.2 関数自身を再帰的に呼び出す - 再帰関数 -
 4.6.3 関数も引数も関数 - 高階関数 -
 4.6.4 「使い捨ての関数」は匿名関数で
4.7 高度な関数のテーマ
 4.7.1 テンプレート文字列をアプリ仕様にカスタマイズする - タグ付きテンプレート文字列 -
 4.7.2 変数はどのような順番で解決されるか - スコープチェーン -
 4.7.3 その振る舞いオブジェクトの如し - クロージャ -
Chapter 5:大規模開発でも通用する書き方を身につける - オブジェクト指向構文 -
5.1 JavaScriptにおけるオブジェクト指向の特徴
 5.1.1 「クラス」はなく「プロトタイプ」
 5.1.2 最もシンプルなクラスを定義する
 5.1.3 コンストラクターで初期化する
 5.1.4 動的にメソッドを追加する
 5.1.5 文脈によって中身が変化する変数 - thisキーワード -
 5.1.6 コンストラクターの強制的な呼び出し
5.2 コンストラクターの問題点とプロトタイプ
 5.2.1 メソッドはプロトタイプで宣言する - prototypeプロパティ -
 5.2.2 プロトタイプオブジェクトを利用することの2つの利点
 5.2.3 プロトタイプオブジェクトの不思議(1) - プロパティの設定 -
 5.2.4 プロトタイプオブジェクトの不思議(2) - プロパティの削除 -
 5.2.5 オブジェクトリテラルでプロトタイプを定義する
 5.2.6 静的プロパティ/静的メソッドを定義する
5.3 オブジェクト継承 - プロトタイプチェーン -
 5.3.1 プロトタイプチェーンの基礎
 5.3.2 継承関係は動的に変更可能
 5.3.3 オブジェクトの型を判定する
5.4 本格的な開発に備えるために
 5.4.1 プライベートメンバーを定義する
 5.4.2 Object.definePropertyメソッドによるアクセサーメソッドの実装
 5.4.3 名前空間/パッケージを作成する
5.5 ES2015のオブジェクト指向構文
 5.5.1 クラスを定義する - class命令 -
 5.5.2 オブジェクトリテラルの改善
 5.5.3 アプリを機能単位にまとめる - モジュール -
 5.5.4 列挙可能なオブジェクトを定義する - イテレーター -
 5.5.5 列挙可能なオブジェクトをより簡単に実装する - ジェネレーター -
 5.5.6 オブジェクトの基本的な動作をカスタマイズする - Proxyオブジェクト -
Chapter 6:HTMLやXMLの文書を操作する - DOM(Document Object Model) -
6.1 DOMの基本を押さえる
 6.1.1 マークアップ言語を操作する標準のしくみ「DOM」
 6.1.2 文書ツリーとノード
6.2 クライアントサイドJavaScriptの前提知識
 6.2.1 要素ノードを取得する
 6.2.2 文書ツリー間を行き来する - ノードウォーキング -
 6.2.3 イベントをトリガーにして処理を実行する - イベントドリブンモデル -
6.3 属性値やテキストを取得/設定する
 6.3.1 多くの属性は「要素ノードの同名のプロパティ」としてアクセスできる
 6.3.2 不特定の属性を取得する
 6.3.3 テキストを取得/設定する
6.4 フォーム要素にアクセスする
 6.4.1 入力ボックス/選択ボックスの値を取得する
 6.4.2 チェックボックスの値を取得する
 6.4.3 ラジオボタンの値を取得する
 6.4.4 ラジオボタン/チェックボックスの値を設定する
 6.4.5 複数選択できるリストボックスの値を取得する
 6.4.6 アップロードされたファイルの情報を取得する
6.5 ノードを追加/置換/削除する
 6.5.1 innerHTMLプロパティとどのように使い分けるか
 6.5.2 新規にノードを作成する
 6.5.3 既存のノードを置換/削除する
 6.5.4 HTMLCollection/NodeListをくり返し処理する場合の注意点
6.6 JavaScriptからスタイルシートを操作する
 6.6.1 インラインスタイルにアクセスする - styleプロパティ -
 6.6.2 外部のスタイルシートを適用する - classNameプロパティ -
 6.6.3 スタイルクラスをより簡単に操作する - classListプロパティ -
6.7 より高度なイベント処理
 6.7.1 イベントリスナー/イベントハンドラーを削除する
 6.7.2 イベントに関わる情報を取得する - イベントオブジェクト -
 6.7.3 イベント処理をキャンセルする
 6.7.4 イベントリスナー/イベントハンドラー配下のthisキーワード
Chapter 7:クライアントサイドJavaScript開発を極める
7.1 ブラウザーオブジェクトで知っておきたい基本機能
 7.1.1 ブラウザーオブジェクトの階層構造
 7.1.2 確認ダイアログを表示する - confirmメソッド -
 7.1.3 タイマー機能を実装する - setInterval/setTimeoutメソッド -
 7.1.4 表示ページのアドレス情報を取得/操作する - locationオブジェクト -
 7.1.5 履歴に沿ってページを前後に移動する - historyオブジェクト -
 7.1.6 JavaScriptによる操作をブラウザーの履歴に残す - pushStateメソッド -
 7.1.7 アプリにクロスブラウザー対策を施す - navigatorオブジェクト -
7.2 デバッグ情報を出力する - Consoleオブジェクト -
 7.2.1 コンソールにログを出力する
 7.2.2 知っておくと便利なログメソッド
7.3 ユーザーデータを保存する - Storageオブジェクト -
 7.3.1 ストレージにデータを保存/取得する
 7.3.2 既存のデータを削除する
 7.3.3 ストレージからすべてのデータを取り出す
 7.3.4 ストレージにオブジェクトを保存/取得する
 7.3.5 ストレージの変更を監視する
7.4 サーバー連携でリッチなUIを実装する - Ajax -
 7.4.1 PHPのHello, WorldとAjaxのHello, Worldを比較してみる
 7.4.2 Ajaxアプリ実装の基本
 7.4.3 Ajaxアプリで構造化データを扱う
 7.4.4 クライアントサイドでクロスオリジン通信を可能にする - JSONP -
 7.4.5 クロスドキュメントメッセージングによるクロスオリジン通信
7.5 非同期処理を簡単に表現する - Promiseオブジェクト -
 7.5.1 Promiseオブジェクトの基本を押さえる
 7.5.2 非同期処理を連結する
 7.5.3 複数の非同期処理を並行して実行する
7.6 バックグラウンドでJavaScriptのコードを実行する - Web Worker -
 7.6.1 ワーカーを実装する
 7.6.2 ワーカーを起動する
Chapter 8:現場で避けて通れない応用知識
8.1 単体テスト - Jasmine -
 8.1.1 Jasmineのインストール方法
 8.1.2 テストの基本
 8.1.3 テストスイートを実行する
8.2 ドキュメンテーションコメントでコードの内容をわかりやすくする - JSDoc -
 8.2.1 ドキュメンテーションコメントの記述ルール
 8.2.2 ドキュメント作成ツール - JSDoc -
8.3 ビルドツールで定型作業を自動化する - Grunt -
 8.3.1 Gruntによるソースコードの圧縮
8.4 今すぐECMAScript2015を実践活用したい - Babel -
 8.4.1 コードを手動で変換する
 8.4.2 Grunt経由でBabelを実行する
 8.4.3 簡易インタプリターを利用する
8.5 読みやすく保守しやすいコードを書く - コーディング規約 -
 8.5.1 JavaScriptの主なコーディング規約
 8.5.2 JavaScript style guide(MDN)の主な規約
 8.5.3 Google標準のコーディングスタイル
Column
JavaScriptを学ぶうえで役立つサイト
外部スクリプトを非同期にロードする - async/defer 属性 -
「JavaScript の代替言語」altJS
JavaScript のスーパーセット、静的型システムを備えたaltJS「TypeScript」
JavaScriptとその周辺技術を学ぶための参考書籍