JavaScriptの先端は圧縮画像機能を実現します。


なぜ先に写真を圧縮しますか?
最近は携帯端末h 5で画像をアップロードする機能をしていますが、本来はこの機能は複雑ではなく、axiosを通じてサーバーに画像ファイルをアップロードするだけでいいです。しかし、今は携帯電話で配られた写真の機能が非常に強いと思います。適当な一枚の写真はややもすれば五、六兆円です。帯域幅も耐えられないので、先端で画像を圧縮するのが必要な一環です。
圧縮効果

まず圧縮の流れを紹介します。
  • 元のinputタグを通じてアップロードする画像ファイル
  • を取得する。
  • は、画像ファイルをimg元素タグ
  • に変換する。
  • .canvas上で圧縮して描画するHTMLImageement
  • は、canvasが描いた画像をblobファイル
  • に変換する。
  • 最後に、このblobファイルをサービス端末
  • に伝えます。
  • 完成
  • 次に詳しい手順を見ます。
    文章と手順の整合性を考慮して、細部ごとに書いていきます。
    1.  Inputタグを使って画像ファイルのリソースを取得します。
    このステップは、最もよくご存知のようですね。オリジナルのinputタグは、type属性がfileであることによって、ユーザにファイルを選択することができます。acceptに選択されたファイルタイプを制限し、オンチャンゲイベントをバインドして、確認後のファイルを取得します。
    
    <input type="file" accept="image/*" />
    コントロールをクリックして、トリガフォーカスをして、ファイルエクスプローラを開けて、ファイルを選択して確認したら、changeイベントをトリガするので、changeイベントのコールバックで選択したファイルを取得できます。このようにしてください。

    2.ファイルを読み込み、ラベル要素に変換する
    画像ファイルを手に入れたら、まずHTMLImage Elementに変えます。つまり普通のimgタグです。具体的にはFileReaderコンストラクタを使います。
    まずnewでは、1つの例として、fileReaderのreadAdata URLというapiを通じて、画像ファイルを読み取り、その戻り値は符号化されたbase 64の文字列であり、この文字列をsrc属性に割り当てて、HTMLImageementに画像ファイルの変換を完了した。
    
    //  new  img fileReader   
    const img = new Image()
    const reader = new FileReader()//       
    reader.readAsDataURL(file) 
    reader.onload = function(e){ 
     img.src = e.target.result
    }
    変換するHTMLImageElement

    3.canvas圧縮、コアステップ
    変換された要素を手に入れたら、まずこの元素の幅の高さを取り出します。この幅の高さは実際の画像ファイルの幅の高さです。
    
    const { width: originWidth, height: originHeight } = img
    次に、最大限度の幅の高さを指定します。この制限の幅の高さを超えると、ズームなどの比率を設定します。
    
     //       
     const maxWidth = 1000,maxHeihgt = 1000
     //          
     let targetWidth = originWidth, targetHeight = originHeight
     //                     
     if (originWidth > maxWidth || originHeight > maxHeight) {
       if (originWidth / originHeight > 1) {
        //    
        targetWidth = maxWidth
        targetHeight = Math.round(maxWidth * (originHeight / originWidth))
       } else {
        //    
        targetHeight = maxHeight
        targetWidth = Math.round(maxHeight * (originWidth / originHeight))
       }
      }
    圧縮するサイズを計算したら、canvasの例を作成し、canvasの幅の高さを圧縮計算したサイズに設定し、上に描画します。
    
    //     
    const canvas = document.createElement('canvas')
    const context = canvas.getContext('2d')
    
    //                  
     canvas.width = targetWidth
     canvas.height = targetHeight
     context.clearRect(0, 0, targetWidth, targetHeight)
     // img      
     context.drawImage(img, 0, 0, targetWidth, targetHeight)
    4.blobファイルに変換する
    canvasの描画が完了したら、toBlobを使って画像をblobファイルに変換できます。このアプリは三つの入力を受け付けます。
    
    canvas.toBlob(callback, type, encoderOptions);
    コールバック関数では変換後のblobファイル、typeは変換するピクチャタイプ、標準のpngが得られます。
    encoder Optionsは、設定されたピクチャフォーマットがimage/jpegまたはimage/webpの場合、ピクチャの展示品質を指定するために使用される。
    ですから、jpgやwebp形式の写真を圧縮するだけなら、第3部の操作は不要です。直接にこのアプリを使って、欲しい品質パラメータを記入すればいいです。でも、実際にはいろんな種類の写真のフォーマットを考えなければならないので、第三部の過程を使う必要があります。
    回転するblobの長さはこのようです。

    5.blobをアップロードし、大成功を収めた。
    完全なコード実現
    全体の過程において、非同期フィードバック操作がありますので、asyncを使って、非同期コードの同期実行を実現しました。
    
    //     file   img  
    function readImg(file) {
     return new Promise((resolve, reject) => {
      const img = new Image()
      const reader = new FileReader()
      reader.onload = function(e) {
       img.src = e.target.result
      }
      reader.onerror = function(e) {
       reject(e)
      }
      reader.readAsDataURL(file)
      img.onload = function() {
       resolve(img)
      }
      img.onerror = function(e) {
       reject(e)
      }
     })
    }
    
    /**
     *     
     *@param img     img  
     * @param type           
     * @param mx              
     * @param mh              
     */
    function compressImg(img, type, mx, mh) {
     return new Promise((resolve, reject) => {
      const canvas = document.createElement('canvas')
      const context = canvas.getContext('2d')
      const { width: originWidth, height: originHeight } = img
      //       
      const maxWidth = mx
      const maxHeight = mh
      //     
      let targetWidth = originWidth
      let targetHeight = originHeight
      if (originWidth > maxWidth || originHeight > maxHeight) {
       if (originWidth / originHeight > 1) {
        //    
        targetWidth = maxWidth
        targetHeight = Math.round(maxWidth * (originHeight / originWidth))
       } else {
        //    
        targetHeight = maxHeight
        targetWidth = Math.round(maxHeight * (originWidth / originHeight))
       }
      }
      canvas.width = targetWidth
      canvas.height = targetHeight
      context.clearRect(0, 0, targetWidth, targetHeight)
      //     
      context.drawImage(img, 0, 0, targetWidth, targetHeight)
      canvas.toBlob(function(blob) {
       resolve(blob)
      }, type || 'image/png') })
    }
    大体過程を実行して、具体的に需要によって、自分で変えます。
    
    async function upload(file){
      const img = await readImg(file)
      const blob = await compressImg(img, file.type, 1000, 1000)
      const formData = new FormData()
      formData.append('file', blob, 'xxx.jpg')
      axios.post('http://xxx.com/api',formData)
    }
    upload(file).catch(e => console.log(e))
    ここでは、JavaScriptの先端について、圧縮画像機能を実現した文章を紹介します。JavaScriptに関する圧縮画像の内容については、以前の文章を検索したり、下記の関連記事を見たりしてください。これからもよろしくお願いします。