HTML 5は携帯電話の写真アップロードを実現

14819 ワード

  • ページスタイル:
  • アップロードにはオリジナルの方法があり、写真だけアップロードしたい場合は、ユーザーが画像アップロードを選択したくない場合は、capture属性を追加することで、camcorder/microphone/camera...、ここでcameraを選択します.PS:この属性にはブラウザ互換性の問題があり、すべてのブラウザがサポートしているわけではありません.
    <input type="file" accept="image/*" capture="camera" >
  • オリジナルfileスタイルが要求を満たしていないため、対応する処理が必要であり、このとき位置決めを使用してinputの上に私たちが望むページ効果を配置します.そして上の要素をクリックすると、私たちのinputをトリガーして画像をアップロードすることができます.この場合の問題は、inputの上の要素をクリックすると、イベントが貫通する必要があります.すなわち、inputをクリックすることに相当します.css 3の新しいプロパティpointer-eventsを使用します.
    //  cursor
    button{
         cursor:pointer;
         pointer-events:none;
    }
    
    ---この時点で画像アップロードのスタイルはすでに処理済み---コードクリップ:
    <style >
        *{
            padding: 0;
            margin: 0;
        }
        .wrapper{
            width: 320px;
            height: 50px;
            margin: 20px auto;
            position: relative;
            border: 1px solid #f0f0f0;
        }
        input{
            width: 100px;
            height: 30px;
        }
        button{
            position: absolute;
            cursor: pointer;
            pointer-events: none;
            width: 100px;
            height: 30px;
            left: 0;
            top: 0;
        }
        a{
            pointer-events: none;
        }
        .img{
            border: 1px solid #ccc;
            padding: 10px;
        }
    style >
    
    <div class = "wrapper">
         <input type = "file" accept= "image/*" capture= "camera" id= "img" />
         <button >     button >
    div >
    
  • ピクチャ圧縮処理:
  • 携帯電話の写真をアップロードするため、今の携帯電話の写真を撮るのはすべてとても大きくて、例えば小米4 S、大きさは3 M以上で、もし原図がアップロードするならば、ユーザーの流量を消耗しすぎて、そこで画像の圧縮の問題を解決します.
  • changeイベントを通じて、画像のアップロードを傍受し、readerAsDataURLを通じてアップロードされた画像を取得する.
    document.getElementById( 'img').addEventListener( 'change', function () {
         var reader = new FileReader();
         reader.onload = function (e) {
              //        :compress();
         };
         reader.readAsDataURL(this.files[0]);
         console.log(this.files[0]);
         var fileSize = Math.round( this.files[0].size/1024/1024) ; // M   
         //this.files[0]      :     , byte     size     :this.files[0].size;
    }, false);
    
  • アップロード画像を圧縮するには、canvas APIを介してcanvasを呼び出す必要がある.toDataURL(type, encoderOptions);画像を一定の圧縮比で圧縮し、base 64符号化する.ポイント:圧縮戦略:まず画像の最大幅or最大高さを設定し、一般的にそのうちの1つを設定すればいいです.すべての携帯電話の幅比の差は大きくないからです.次に、ピクチャの最大サイズ、allowMaxSizeを設定し、ピクチャの実際のサイズと最大許容サイズに基づいて、対応する圧縮比率を設定します.
    //      :
    1、           or   ;
    2、      ,       size  ,        。
    
    function compress(res,fileSize) { //res       ,fileSize       
        var img = new Image(),
            maxW = 640; //      
    
        img.onload = function () {
            var cvs = document.createElement( 'canvas'),
                ctx = cvs.getContext( '2d');
    
            if(img.width > maxW) {
                img.height *= maxW / img.width;
                img.width = maxW;
            }
    
            cvs.width = img.width;
            cvs.height = img.height;
    
            ctx.clearRect(0, 0, cvs.width, cvs.height);
            ctx.drawImage(img, 0, 0, img.width, img.height);
    
            var compressRate = getCompressRate(1,fileSize);
    
            var dataUrl = cvs.toDataURL( 'image/jpeg', compressRate);
    
            document.body.appendChild(cvs);
            console.log(dataUrl);
        }
    
        img.src = res;
    }
    
    function getCompressRate(allowMaxSize,fileSize){ //      ,size   MB
          var compressRate = 1;
    
          if(fileSize/allowMaxSize > 4){
               compressRate = 0.5;
          } else if(fileSize/allowMaxSize >3){
               compressRate = 0.6;
          } else if(fileSize/allowMaxSize >2){
               compressRate = 0.7;
          } else if(fileSize > allowMaxSize){
               compressRate = 0.8;
          } else{
               compressRate = 0.9;
          }
    
          return compressRate;
    }
    

  • 画像をサーバにアップロードします.
  • ピクチャは圧縮が完了したが、圧縮されたピクチャはFileではなくbase 64符号化であり、2つの選択に等しい:1、Stringの形式でbase 64符号化をサーバにアップロードし、サーバはbase 64をimgピクチャに転送する.2、フロントエンドはbase 64をFileピクチャタイプに変換し、サーバにアップロードする.
  • 方法1:圧縮後にbase 64をバックグラウンドに直接アップロードし、簡単を実現する.
  • 方法2:フロントエンドは自分でbase 64ビットFile画像を転送し、これはフロントエンドに対して圧力が大きい.理由:html 5 canvasはクライアントAPIに属し、画像をハードディスクに保存する権限がなく、canvasだけがある.toDataURL()というインタフェースは、キャンバスのbase 64符号化を導出し、サーバに処理保存を提供することができる.したがって、base 64符号化をピクチャに変換するにはnodeJsを借りる必要がある.nodeJSには関連ファイル処理のAPIがあるからです.
    //  nodeJS base64     
    var express = require('express');
    var fs = require("fs");
    var app = module.exports = express();
    
    function dataToImage(dataUrl){
        var base64Data = dataUrl.replace(/^data:image\/\w+;base64,/,'');
        var dataBuffer = new Buffer(base64Data,'base64');
    
        fs.writeFile('out.jpg',dataBuffer,function(err){
            if(err){
                console.log(err);
            }else{
                console.log('Success...');
            }
        });
    }
    
    dataToImage('data:image/jpeg;base64,/9...'); //    base64  ,    ...
    
    if(!module.parent){
        app.listen(8000);
        console.log('Express started on port 8000');
    }
    
    Summary:nodeJSを使用する場合、nodeJSコードをサーバに個別に配備する必要がある場合は、論理全体が面倒になります.2つの方法を総合的に比較し、第1の方法を推奨し、base 64をサーバに直接伝え、バックグラウンドで対応する変換を処理します.