canvasにおけるtoData URL()を利用して画像をdata URL(base 64)に変換する方法を詳しく説明する。


写真をbase 64に変換するメリット
画像をBase 64符号化に変換すると、ファイルをアップロードしない条件で他のページやエディタに画像を挿入することができます。これは小さい写真にとってとても便利です。写真を保存するところを探す必要がないからです。
画像をbase 64に変換して符号化する場合、ウェブ上では一般的に小さいピクチャに使用され、ピクチャの要求数(js、cssコードに集合する)を減らすだけでなく、いくつかの相対パスなどの問題でピクチャ404のエラーを防ぐことができる。
ことばを引く
アプリケーションシーンを仮定すると、ある特殊な理由により、サービス端末から画像パスを要求され、当該パスを通じて対応するピクチャのbase 64 data URLを取得することが要求される。このシーンでは、まず、画像経路がアクセス可能であると推測するとともに、画像をdata URLに変換する方法が必要である。
私たちはどうやってそれを実現しますか?
data URL
まず、正統なdata URLの文法を概観してみると、変換後の内容が正しいかどうかを確認するのに役立ちます。完全なdataURIはこのようなはずです。

data:[<mediatype>][;base64],<data>
この中でmediatypeはファイルタイプを宣言しました。MIMEルールに従います。例えば、「image/png」、「text/playin」。その後はコードタイプです。ここではbase 64だけを扱っています。続いてファイルコードの内容です。私たちはよくHTMLでこのように書いているのを見ます。

src="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7"
これはbase 64で符号化されたdata URLを参照してください。ブラウザがサポートすれば、gif画像に復号してレンダリングすることができます。
.toData URL()
FileReaderオブジェクトも同様の方法があります。例えば.readAsDataURL()ですが、fileまたはblobタイプしか受け入れられません。この2つのタイプは一般に<input[type=file]>要素のfiles属性でしか取得できません。またはBlob()構造関数で新しいオブジェクトを作成します。ばつが悪いのは、現在は画像パスだけで、ブラウザのセキュリティポリシーによって制限されています。<input[type=file]>のfiles属性は読み取り専用です。Blob()構造関数はファイルの内容だけを受け入れています。両方の方法は画像経路を通じて直接取得できません。上記で仮定されたアプリケーションシーンは、経路を通して画像コンテンツを取得する方法をまず考慮しなければならない。[img]は可能であり、[canvas]に描かれることができ、[canvas]はちょうど.toDataURL()の方法を持っている。
すべてのものが備えられています。私たちは取得した画像を‘canvas’に入れて.toDataURL()方法で変換するだけで、base 64で符号化されたdata URLを得ることができます。この方法の文法を見に来ました。

canvas.toDataURL([type, encoderOptions]);
canvasはDOM元素オブジェクトです。パラメータtypeは、ピクチャタイプを指定します。指定されたタイプがサポートされていない場合は、デフォルト値image/pngで置換します。encoder Optionsはイメージ/jpegまたはイメージ/webpタイプのピクチャのためにピクチャ品質を設定できます。
ダタURLに変換する前に、まず画像のローディングが成功していることを確認しなければならないので、.toDataURL()方法は
ワンロード非同期イベントに書くべきです。機能関数を実行します。

 function getBase64(url){
  //           img   ,    src           ,   createElement()    <img>     append(),            
  var Img = new Image(),
   dataURL='';
  Img.src=url;
  Img.onload=function(){ //           ,       
   var canvas = document.createElement("canvas"), //  canvas  
    width=Img.width, //  canvas        
    height=Img.height;
   canvas.width=width;
   canvas.height=height;
   canvas.getContext("2d").drawImage(Img,0,0,width,height); //      canvas 
   dataURL=canvas.toDataURL('image/jpeg'); //     dataURL
  };
 }
いつでも使える変換関数が完成しました。画像がロードされた後、data URL文字列全体が返されます。
完全である
オンラインイベントは、ロード後に変換タスクが実行されることを確認しましたが、新しい問題をもたらしました。data URLは画像ロードが完了してから戻ってきます。画像がいつロードされるかは確認できません。その後、data URLに関連した処理を行う場合(例えば、他のサーバに転送する)は、フィードバックを追加する必要があります。これは後続の処理タスクがdata URLを取得した後に実行されることを確保するために、getBase64() を修正する必要があります。

 function getBase64(url,callback){ //        
  ...
  Img.onload=function(){
   ...
   canvas.getContext("2d").drawImage(Img,0,0,width,height);
   dataURL=canvas.toDataURL('image/jpeg');
   callback?callback(dataURL):null; //      
  };
 }
実行時にコールバックを追加します。

 getBase64('//upload.jianshu.io/users/upload_avatars/555630/fdd1b798e6b0.jpg',(dataURL)=>{
  console.log(dataURL);
 });
このように、互換性を考えないなら、プロミセとゲナートで実現できるかもしれません。エラーを追加して処理すれば完璧です。
締め括りをつける
以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考となる学習価値を持っています。質問があれば、メッセージを書いて交流してください。ありがとうございます。