今回は、H5 を使用して画像をアップロードする方法と、H5 を使用して画像をアップロードするための注意事項について説明します。実際の事例を見てみましょう。 私は数日前にプロジェクトに取り組んでいましたが、モジュールの 1 つはサーバーへの画像のアップロードに関係していました。今日、時間をかけて整理してみましたが、整理すればするほど、より多くの知識ポイントが含まれることがわかりました。次の例は、Baidu の検索マップを参照しています。
知識ポイント: 入力ファイル、base64、FileReader、キャンバス圧縮、BLOB、BTOA エンコードと atob デコード、FormData。
html dom ノード:
<input type="file">
1.var filereader = new fileReader();
3. ステータス定数
定数名
値
説明
0 | ファイルの読み取りを開始 | |
1 | ファイル読み込み | DONE |
ファイル読み込み完了 | 以下例では、現在のステータス別々に読むことができます。 | |
属性名 | 説明 |
error
準備完了状態 | current fileReader オブジェクトのステータスは、上記のステータス定数のいずれかです | |||||||||||||||||||||||||||
result | 読み取られたコンテンツ | |||||||||||||||||||||||||||
メソッド名 | パラメータ | 説明 |
abort | なし | 読み込みを中止します。非 LOADING 状態のときに呼び出されます。 は例外をスローします |
readAsArrayBuffer | blob/file | は配列として読み取られ、読み取られたコンテンツの結果にはArrayBufferオブジェクトがあります |
readAsBinaryString | blob/file | はバイナリとして読み取られ、その結果には読み取られたファイルの元のバイナリが含まれます |
readAsDataUrl | blob/file | 読むas dataUrl、in 結果には、読み取ったコンテンツを表す data:url 形式の文字列があります |
readAsTexx | blob/file、[エンコーディング] | はテキストとして読み取られ、そして結果の文字列は、読み取られたContent |
6を表します。
中断されたときにトリガーonerror | エラーが発生したときにトリガーされます |
onload | 読み取りが成功したときにトリガーされます |
onloadend | 読み取りが完了するとトリガーされます(成功かどうか) |
onloadstart | 読み取り開始時にトリガー |
onprocess | 読み取り中にトリガー |
BASE64: 我们用chrome打开一张图片,在resources里面显示的就是图片的base编码(实际上base编码比原图片稍大) 图片的base64编码也就是将一张图片编码成一个字符串,我们可以用这个字符串给img标签的src赋值,这样我们就可以看到这张图片。 如何编写: 在html中: <span style="font-size: 14px;"><img src="data:image/gif;base64,R0lGODlhAwADAIABAL6+vv///yH5BAEAAAEALAAAAAADAAMAAAIDjA9WADs="></span> ログイン後にコピー 在css中: <span style="font-size: 14px;">background-image:url(data:image/gif;base64,R0lGODlhBAABAIABAMLBwfLx8SH5BAEAAAEALAAAAAAEAAEAAAICRF4AOw==);</span> ログイン後にコピー 优缺点: 优点:1、减少了http请求;2、可以被gzip;3、没有跨域问题;4、无需考虑在更新图片时缓存问题。 缺点:1、ie8以下不支持;2、不论是写在css文件还是html文件中,增加了文件的大小;3、图片大了之后,程序员编码相当困难; 应用: 根据实际需求来选择base64显示图片,或者选择css sprite,或者直接使用png等 一般使用场景:很少被更新,实际尺寸很小,在系统中大量使用。 canvas压缩: 在移动应用场景中,用户上传的图片一般很大,会导致上传时间过长而失败,既浪费时间也浪费流量,更影响用户体验。我们可以使用canvas的drawImage方法的图形裁剪功能。 1、新建image对象,给其src复制base64值,在其监听onload事件; 2、在onload事件方法中新建canvas对象,获取上下文context; 3、设置裁剪比例,调用drawImage方法填充图片。 4、通过toDataUrl方法获取裁剪之后的base64值。 详细见下例。 Blob 在传输一些比较大的图片的base64是容易出现转发错误,这里我们可以将base64转换成blob字段写到form表单中提交到后台。一般blob和base64之间的相互转换通过fileReader 的readAsDataUrl和ArrayBuffer的charCodeAt方法。下面列举几个相互转换的方法。来自(http://jsperf.com/blob-base64-conversion) <span style="font-size: 14px;"> var blobToBase64 = function(blob, cb) {<br> var reader = new FileReader();<br> reader.onload = function() {<br> var dataUrl = reader.result;<br> var base64 = dataUrl.split(',')[1];<br> cb(base64);<br> };<br> reader.readAsDataURL(blob);<br> };<br> var base64ToBlob = function(base64, cb) {<br> var binary = atob(base64);<br> var len = binary.length;<br> var buffer = new ArrayBuffer(len);<br> var view = new Uint8Array(buffer);<br> for (var i = 0; i < len; i++) {<br/> view[i] = binary.charCodeAt(i);<br/> }<br/> cb(new Blob([view]));<br/> };<br/> var base64ToBlobSync = function(base64) {<br/> var binary = atob(base64);<br/> var len = binary.length;<br/> var buffer = new ArrayBuffer(len);<br/> var view = new Uint8Array(buffer);<br/> for (var i = 0; i < len; i++) {<br/> view[i] = binary.charCodeAt(i);<br/> }<br/> var blob = new Blob([view]);<br/> return blob;<br/> };<br/> var blobToBase64_2 = function(blob, cb) {<br/> var reader = new FileReader();<br/> reader.onload = function() {<br/> var buffer = reader.result;<br/> var view = new Uint8Array(buffer);<br/> var binary = String.fromCharCode.apply(window, view);<br/> var base64 = btoa(binary);<br/> cb(base64);<br/> };<br/> reader.readAsArrayBuffer(blob);<br/> };</span> ログイン後にコピー btoa 与 atob: ---在对base64转blob时就需要用atob对base64进行解码 btoa("javascript"); //"amF2YXNjcmlwdA==" atob("amF2YXNjcmlwdA==") ; //"javascript" ログイン後にコピー 注意:在需要转码中文时,需要用encodeURIComponent方法对中文处理,解码时用decodeURIComponent btoa(encodeURIComponent("我喜欢 javascript")); //"JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA==" decodeURIComponent(atob("JUU2JTg4JTkxJUU1JTk2JTlDJUU2JUFDJUEyJTIwamF2YXNjcmlwdA==")); //"我喜欢 javascript" FormData: ログイン後にコピー 我们只需要使用new FormData()创建对象,然后append键值对,后用ajax向后台发生即可。 这里是往FormData对象添加blob字段。 注:使用Ajax将这个 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"> <title>Document</title> <script src="http://apps.bdimg.com/libs/zepto/1.1.4/zepto.min.js"></script> <!--引用baidu--> </head> <style> .uploadPic{ width: 92%; position: relative; margin: 0 auto; height: 2.8rem; line-height: 2.8rem; font-size: 1.3rem; border-radius: 4px; color: #fff; text-align: center; background-color: #72bcc5; } .uploadPic>input{ position: absolute; display: block; width: 100%; height: 100%; right: 0; top: 0; opacity: 0; } .uploadPic>img{ border:none; } </style> <body> <p id="uploadPic" class="uploadPic"> <span>拍摄</span> <input type="file" > <!--这里可以添加multiple="true"属性,用来添加多张图片,然后对this.file[]数组操作--> <p style="line-height: 1rem;margin: 0.5rem 0;"><progress id="progress" value="0" max="100" style="width: 100%;"></progress></p> <img src="" width="100%" style="height: 21rem;"> </p> </body> <script> function upload(file, callBack) { var loading=0; var total=file.size; if(window.FileReader){ $("#progress")[0].value=0; var fileReader = new FileReader(); fileReader.onload = function() { console.log(fileReader.readyState); //读取完成 compressPic(this.result,callBack) }; fileReader.onerror = function() { console.log(fileReader.error); }; fileReader.onprogress = function (e){ console.log(fileReader.readyState); //读取中 loading += e.loaded; $("#progress")[0].value=(loading / total) * 100; } console.log(fileReader.readyState); //未读取 fileReader.readAsDataURL(file) }else{ alert("您的浏览器不支持FileReader"); } } function base64ConvertToBlob(picData, type, size) { type = type || ""; size = size || 512; var decodeFileData = atob(picData); //此处用atob解码,转码函数btoa。在使用方法时注意操作中文时,需对中文decodeURIComponent转换 var dataArray = []; var len = decodeFileData.length; for (var i = 0; i < len; i += size) { var pieceData = decodeFileData.slice(i, i + size); //这里做了一个512的分组 var arr = new Array(pieceData.length); for (var j = 0; j < pieceData.length; j++) { arr[j] = pieceData.charCodeAt(j) } var u8a = new Uint8Array(arr); dataArray.push(u8a) } return new Blob(dataArray, {type: type}) } function compressPic(picData,callBack) { var img=new Image(); img.onload = function(){ var width = img.width; var height = img.height; var standard=800; //以800为基准压缩 if (width > standard || height > standard) { var rate = Math.max(width / standard, height / standard); width /= rate; height /= rate } var canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; var context = canvas.getContext("2d"); context.fillRect(0, 0, canvas.width, canvas.height); context.drawImage(img, 0, 0, width, height); var data = canvas.toDataURL("image/jpeg", 1); //var blobData=base64ConvertToBlob(data.replace(/^.*?,/, ""), "image/jpeg") //-----需要去掉符号,不然使用atob方法报错 //doAjax(new FormData().append('image',data)); //后续可以这样做,转换成Blob字段,组装FormData,发送至后台 console.log("the after canvas compress size : " + data.length); callBack(data) }; img.src=picData; console.log("the before canvas conpress size : "+picData.length); } $("#uploadPic input").change(function() { var file=this.files[0]; upload(file, function(picData){ $("#uploadPic img")[0].src = picData; //预览 } ); }); </script> </html></span> ログイン後にコピー 相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章! 推荐阅读: |
以上がH5 を使用して写真をアップロードする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。