この記事では、主にモバイル端末での圧縮画像アップロード機能を実現するための H5 の使用方法を詳しく紹介します。興味のある友人は参考にしてください。
以前、同僚がモバイルでのキャンバス圧縮の使用について話してくれました。最近暇なので写真アップロード機能を実践してみました。デモエフェクトのリンクは記事の下部に掲載されています。
携帯端末に写真をアップロードする場合、ユーザーは携帯電話でローカル写真をアップロードしますが、iPhone6 を例に挙げると、通常、アップロードする場合、多くの写真のサイズは 1 メガバイトまたは 2 メガバイトになります。ユーザーがモバイルデータを使用している場合、画像を完全にアップロードすることは明らかに良い考えではありません。
現在、HTML5 のさまざまな新しい API がモバイル Webkit に適切に実装されています。 caniuse 氏によると、このデモで使用されている FileReader、Blob、および Formdata オブジェクトは、ほとんどのモバイル デバイスのブラウザー (safari6.0 以降、Android 3.0 以降) に実装されているため、フロントエンドで直接画像を圧縮することが重要になっています。モバイル端末に画像をアップロードする機能。
モバイル端末での画像の圧縮やアップロードには主にfilereader、canvas、formdataの3つのh5 APIが使用されます。ロジックは難しくありません。全体のプロセスは次のとおりです:
(1) ユーザーが入力ファイルを使用して画像をアップロードする場合、ファイルリーダーを使用してユーザーがアップロードした画像データ (base64 形式) を読み取ります
(2) 画像データを img オブジェクトに渡します、そして、ページ上のキャンバスにimgを描画し、canvas.toDataURLを呼び出して画像を圧縮します
(3) 圧縮されたbase64形式の画像データを取得し、バイナリに変換してformdataに挿入し、formdataを送信しますXmlHttpRequest を通じて。
この3ステップで画像の圧縮とアップロードが完了します。
簡単そうに聞こえますが、実際にはまだ落とし穴がいくつかあります。次に、コードで直接解析してみましょう:
【1】画像データを取得します
まず、画像データを取得します。つまり、入力ファイルの変更イベントをリッスンし、アップロードされたファイルオブジェクトファイルを取得します。 、配列のようなファイルを配列に変換し、forEach 走査を実行します。
次に、ファイルの種類を決定します。写真でない場合は処理されません。画像の場合は、ファイルリーダーをインスタンス化し、アップロードされたファイル データを Base64 形式で読み取り、データ長を決定します。画像が 200KB より大きい場合は、compress メソッドを呼び出して圧縮し、それ以外の場合は、upload メソッドを呼び出してアップロードします。
filechooser.onchange = function () { if (!this.files.length) return; var files = Array.prototype.slice.call(this.files); if (files.length > 9) { alert("最多同时只可上传9张图片"); return; } files.forEach(function (file, i) { if (!/\/(?:jpegpnggif)/i.test(file.type)) return; var reader = new FileReader(); var li = document.createElement("li"); li.innerHTML = "<p class="progress"><span></span></p>"; $(".img-list").append($(li)); reader.onload = function () { var result = this.result; var img = new Image(); img.src = result; //如果图片大小小于200kb,则直接上传 if (result.length <= maxsize) { $(li).css("background-image", "url(" + result + ")"); img = null; upload(result, file.type, $(li)); return; } // 图片加载完毕之后进行压缩,然后上传 if (img.complete) { callback(); } else { img.onload = callback; } function callback() { var data = compress(img); $(li).css("background-image", "url(" + data + ")"); upload(data, file.type, $(li)); img = null; } }; reader.readAsDataURL(file); }) };
【2】画像を圧縮する
上記の画像データの取得が完了したら、画像を圧縮する方法を使用できるようになります。画像の圧縮には、画像をキャンバスに直接描画してから toDataURL を呼び出す必要はありません。
IOSでは、キャンバス上に画像を描画する際に2つの制限があります:
1つ目は画像のサイズです。画像のサイズが200万ピクセルを超える場合、画像はキャンバス上に描画できず、エラーも発生しません。は、drawImage を呼び出すときに報告されますが、toDataURL を使用して画像データを取得すると、空の画像データが取得されます。
さらに、キャンバスのサイズが制限されており、キャンバスのサイズが約500万ピクセル(幅と高さの積)を超えると、絵が描画できないだけでなく、他のものも描画できなくなります。 。
最初の制限に対処するには、解決策はタイルを描画することです。タイル描画とは画像を複数に分割してキャンバス上に描画することですが、私のコードでは画像を100万ピクセルに分割してキャンバス上に描画する方法をとっていました。
2番目の制限に対処するための私の解決策は、安全のために画像の幅と高さを適切に圧縮することです。画像が400万より大きい場合、コードに設定されている上限は400万ピクセルです。ピクセルの場合、4 メガピクセル未満に圧縮されます。 4 メガピクセルの画像で十分なため、幅と高さは 2000X2000 になります。
これでIOSの2つの制限が解決されました。
上記の制限に加えて、2 つの落とし穴があります。1 つは、canvas の toDataURL が jpg しか圧縮できないことです。ユーザーがアップロードした画像が png である場合、それを jpg に変換する必要があります。つまり、canvas.toDataURL() "image/jpeg", 0.1) では、タイプは一律 jpeg に設定され、圧縮率は独自に制御されます。
もう1つは、pngをjpgに変換する場合、キャンバスに描画するときに、キャンバスに透明な領域がある場合、jpgに変換すると透明な領域が黒くなります。キャンバスのデフォルトは rgba(0,0, 0,0) なので、jpg に変換すると rgba(0,0,0,1) になります。つまり、透明な背景は黒になります。解決策は、描画する前にキャンバスに白い背景を置くことです。
function compress(img) { var initSize = img.src.length; var width = img.width; var height = img.height; //如果图片大于四百万像素,计算压缩比并将大小压至400万以下 var ratio; if ((ratio = width * height / 4000000)>1) { ratio = Math.sqrt(ratio); width /= ratio; height /= ratio; }else { ratio = 1; } canvas.width = width; canvas.height = height; // 铺底色 ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, canvas.width, canvas.height); //如果图片像素大于100万则使用瓦片绘制 var count; if ((count = width * height / 1000000) > 1) { count = ~~(Math.sqrt(count)+1); //计算要分成多少块瓦片 // 计算每块瓦片的宽和高 var nw = ~~(width / count); var nh = ~~(height / count); tCanvas.width = nw; tCanvas.height = nh; for (var i = 0; i < count; i++) { for (var j = 0; j < count; j++) { tctx.drawImage(img, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh); ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh); } } } else { ctx.drawImage(img, 0, 0, width, height); } //进行最小压缩 var ndata = canvas.toDataURL("image/jpeg", 0.1); console.log("压缩前:" + initSize); console.log("压缩后:" + ndata.length); console.log("压缩率:" + ~~(100 * (initSize - ndata.length) / initSize) + "%"); tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0; return ndata; }
[3] 画像のアップロード
画像の圧縮が完了したら、最初にbase64データを文字列に変換し、次にArrayBufferをインスタンス化し、その文字列を変換します。 ArrayBuffer を 8 ビット整数の形式で渡し、BlobBuilder または Blob オブジェクトを通じて 8 ビット整数 ArrayBuffer をバイナリ オブジェクト BLOB に変換し、その BLOB オブジェクトを formdata に追加して、それをバックグラウンドに送信します。アヤックス。
XmlHttpRequest2 はビッグデータを送信できるだけでなく、送信進捗状況の取得などの追加 API も備えており、これもコードに簡単に実装しました。
// 图片上传,将base64的图片转成二进制对象,塞进formdata上传 function upload(basestr, type, $li) { var text = window.atob(basestr.split(",")[1]); var buffer = new ArrayBuffer(text.length); var ubuffer = new Uint8Array(buffer); var pecent = 0 , loop = null; for (var i = 0; i < text.length; i++) { ubuffer[i] = text.charCodeAt(i); } var Builder = window.WebKitBlobBuilder window.MozBlobBuilder; var blob; if (Builder) { var builder = new Builder(); builder.append(buffer); blob = builder.getBlob(type); } else { blob = new window.Blob([buffer], {type: type}); } var xhr = new XMLHttpRequest(); var formdata = new FormData(); formdata.append("imagefile", blob); xhr.open("post", "/cupload"); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { console.log("上传成功:" + xhr.responseText); clearInterval(loop); //当收到该消息时上传完毕 $li.find(".progress span").animate({"width": "100%"}, pecent < 95 ? 200 : 0, function () { $(this).html("上传成功"); }); $(".pic-list").append("<a href="" + xhr.responseText + " rel="external nofollow" ">" + xhr.responseText + "<img src="/static/imghwm/default1.png" data-src="" + xhr.responseText + " class="lazy" + xhr.responseText + "" / alt="モバイル端末はH5を使用して画像アップロードの圧縮機能を実装します" ></a>") } }; //数据发送进度,前50%展示该进度 xhr.upload.addEventListener("progress", function (e) { if (loop) return; pecent = ~~(100 * e.loaded / e.total) / 2; $li.find(".progress span").css("width", pecent + "%"); if (pecent == 50) { mockProgress(); } }, false); //数据后50%用模拟进度 function mockProgress() { if (loop) return; loop = setInterval(function () { pecent++; $li.find(".progress span").css("width", pecent + "%"); if (pecent == 99) { clearInterval(loop); } }, 100) } xhr.send(formdata); }
至此,整个上传的前端图片压缩就完成了,因为是用了formdata提交,所以后台接数据的时候就跟普通form表单提交数据一样处理即可。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
以上がモバイル端末はH5を使用して画像アップロードの圧縮機能を実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

この記事では、&lt; audio&gt;を使用してHTML5にオーディオを埋め込む方法について説明します。フォーマット選択のベストプラクティス(MP3、OGG Vorbis)、ファイルの最適化、および再生のためのJavaScriptコントロールを含む要素。 複数のオーディオfを使用して強調しています

この記事では、HTML5ページの可視性APIを使用して、ページの可視性を検出し、ユーザーエクスペリエンスを向上させ、リソースの使用量を最適化します。重要な側面には、メディアの一時停止、CPU負荷の削減、視認性の変化に基づいて分析の管理が含まれます。

この記事では、JavaScriptを使用してインタラクティブなHTML5ゲームの作成を詳述しています。 ゲームデザイン、HTML構造、CSSスタイリング、JavaScriptロジック(イベント処理とアニメーションを含む)、およびオーディオ統合をカバーしています。 必須JavaScriptライブラリ(Phaser、PI

この記事では、HTML5フォームを作成および検証する方法について説明します。 &lt; form&gt;の詳細要素、入力タイプ(テキスト、電子メール、番号など)、および属性(必須、パターン、MIN、最大)。 HTML5の利点は、古い方法よりも形成されます

この記事では、ビューポートメタタグを使用してモバイルデバイスのページスケーリングを制御し、最適な応答性とパフォーマンスのために幅や初期スケールなどの設定に焦点を当てています。

この記事では、Geolocation APIを使用してユーザーの場所のプライバシーと許可を管理し、アクセス許可を要求するためのベストプラクティスを強調し、データセキュリティを確保し、プライバシー法を遵守することについて説明します。

この記事では、HTML5通知APIを使用してデスクトップ通知を表示する方法について説明し、許可要件、カスタマイズ、およびブラウザーサポートに焦点を当てています。

この記事では、HTML5ドラッグアンドドロップAPIを使用してインタラクティブなユーザーインターフェイスを作成し、要素をドラッグ可能にし、キーイベントを処理し、カスタムフィードバックを使用してユーザーエクスペリエンスを強化する手順を作成する方法について説明します。また、aへの一般的な落とし穴についても説明します


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

ドリームウィーバー CS6
ビジュアル Web 開発ツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

SAP NetWeaver Server Adapter for Eclipse
Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

mPDF
mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター
