ホームページ ウェブフロントエンド jsチュートリアル モバイル フロントエンドの画像圧縮およびアップロード機能を使用するにはどうすればよいですか?

モバイル フロントエンドの画像圧縮およびアップロード機能を使用するにはどうすればよいですか?

Jun 22, 2018 pm 03:51 PM
アップロード 画像圧縮

以下のエディターは、モバイル フロントエンドで画像を圧縮してアップロードする例を共有します。非常に良い参考値となっておりますので、皆様のお役に立てれば幸いです。編集者が来て、一緒に見てみましょう

要約: 私は以前、小さなゲームプラットフォームのプロジェクトに取り組んでいたのですが、アバターをアップロードする機能を含む「ユーザーセンター」モジュールがありました。携帯端末に写真をアップロードする場合、アップロードされる写真はすべて携帯電話のローカル写真であり、現在のスマートフォンを例に取ると、通常、アップロードする写真のサイズは比較的大きいものが多くなります。ユーザーがモバイルデータを使用している場合、画像を完全にアップロードすることは明らかに良い考えではありません。したがって、インターネットで多くの情報を検索した結果、画像を圧縮してアップロードできるのに、iOS ではアップロードできないなど、多くの落とし穴に遭遇しました。 iOS ピットについて知るのに長い時間がかかりました。これは実際に実行可能であることが証明されており、バックエンドで必要な数メガバイトの画像を 200k 以内に圧縮できます。このような実現可能な方法は、皆さんに見せなければなりません(追伸:すべて他人の方法をつなぎ合わせて作られたものです、へへ~)。

現在、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に挿入し、XmlHttpRequestを通じてformdataを送信します。

この3ステップで画像の圧縮とアップロードが完了します。

簡単そうに聞こえますが、実際にはまだ落とし穴がいくつかあります。次に、コードを直接使用して分析します:

[1] 画像データを取得します

まず画像データを取得します。つまり、入力ファイルの変更イベントをリッスンし、アップロードされたファイルを取得します。ファイル オブジェクト ファイルを追加し、配列のような Convert files を配列に追加して、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 (!/\/(?:jpeg|png|gif)/i.test(file.type)) return;
  var reader = new FileReader();
  var li = document.createElement("li");
  li.innerHTML = &#39;<p class="progress"><span></span></p>&#39;;
  $(".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に変換すると透明な領域が黒くなります。 Canvas のデフォルトは 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(&#39;image/jpeg&#39;, 0.1);
 console.log(&#39;压缩前:&#39; + initSize);
 console.log(&#39;压缩后:&#39; + ndata.length);
 console.log(&#39;压缩率:&#39; + ~~(100 * (initSize - ndata.length) / initSize) + "%");
 tCanvas.width = tCanvas.height = canvas.width = canvas.height = 0;
 return ndata;
}
ログイン後にコピー

【三】写真アップロード

完成图片压缩后,就可以塞进formdata里进行上传了,先将base64数据转成字符串,再实例化一个ArrayBuffer,然后将字符串以8位整型的格式传入ArrayBuffer,再通过BlobBuilder或者Blob对象,将8位整型的ArrayBuffer转成二进制对象blob,然后把blob对象append到formdata里,再通过ajax发送给后台即可。

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(&#39;imagefile&#39;, blob);
 xhr.open(&#39;post&#39;, &#39;/cupload&#39;);
 xhr.onreadystatechange = function() {
  if (xhr.readyState == 4 && xhr.status == 200) {
   console.log(&#39;上传成功:&#39; + xhr.responseText);
   clearInterval(loop);
   //当收到该消息时上传完毕
   $li.find(".progress span").animate({
    &#39;width&#39;: "100%"
   }, pecent < 95 ? 200 : 0, function() {
    $(this).html("上传成功");
   });
   $(".pic-list").append(&#39;<a href="&#39; + xhr.responseText + &#39;">&#39; + xhr.responseText + &#39;<img src="&#39; + xhr.responseText + &#39;" /></a>&#39;)
  }
 };
 //数据发送进度,前50%展示该进度
 xhr.upload.addEventListener(&#39;progress&#39;, function(e) {
  if (loop) return;
  pecent = ~~(100 * e.loaded / e.total) / 2;
  $li.find(".progress span").css(&#39;width&#39;, pecent + "%");
  if (pecent == 50) {
   mockProgress();
  }
 }, false);
 //数据后50%用模拟进度
 function mockProgress() {
  if (loop) return;
  loop = setInterval(function() {
   pecent++;
   $li.find(".progress span").css(&#39;width&#39;, pecent + "%");
   if (pecent == 99) {
    clearInterval(loop);
   }
  }, 100)
 }
 xhr.send(formdata);
}
ログイン後にコピー

至此,整个上传的前端图片压缩就完成了,因为是用了formdata提交,所以后台接数据的时候就跟普通form表单提交数据一样处理即可。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

在Webpack中如何加载SVG

在vue-cli中如何实现移动端自适应

在Vue 组件Toast中如何实现显示框效果

有关webpack中rules参数处理

以上がモバイル フロントエンドの画像圧縮およびアップロード機能を使用するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

FastAPI でファイルのアップロードと処理を実装する方法 FastAPI でファイルのアップロードと処理を実装する方法 Jul 28, 2023 pm 03:01 PM

FastAPI でファイルのアップロードと処理を実装する方法 FastAPI は、使いやすく強力な最新の高パフォーマンス Web フレームワークで、ファイルのアップロードと処理のネイティブ サポートを提供します。この記事では、FastAPI フレームワークでファイルのアップロードおよび処理関数を実装する方法を学び、具体的な実装手順を示すコード例を示します。まず、必要なライブラリとモジュールをインポートする必要があります: fromfastapiimportFastAPI,UploadF

PHP を使用してリモート画像を保存するときに画像圧縮を処理するにはどうすればよいですか? PHP を使用してリモート画像を保存するときに画像圧縮を処理するにはどうすればよいですか? Jul 15, 2023 pm 03:57 PM

PHP を使用してリモート画像を保存するときに画像圧縮を処理するにはどうすればよいですか?実際の開発では、ネットワークから画像を取得してローカルサーバーに保存する必要があることがよくあります。ただし、一部のリモート画像は大きすぎる場合があるため、ストレージ容量を減らし、読み込み速度を上げるために画像を圧縮する必要があります。 PHP は、画像圧縮を処理するための強力な拡張機能をいくつか提供しています。その中で最もよく使用されるのは、GD ライブラリと Imagick ライブラリです。 GD ライブラリは、画像の作成、編集、保存のための多くの機能を提供する人気のある画像処理ライブラリです。ここに用途があります

Win10パソコンでアップロード速度が遅い問題を解決する方法 Win10パソコンでアップロード速度が遅い問題を解決する方法 Jul 01, 2023 am 11:25 AM

Win10コンピュータのアップロード速度が遅い場合、どうすれば解決できますか?コンピュータを使用しているときに、ファイルのアップロード速度が非常に遅いと感じることがありますが、これはどういうことでしょうか?実際、これはコンピュータのデフォルトのアップロード速度が 20% であるため、アップロード速度が非常に遅いためです。詳細な操作方法を知らない友人も多いです。編集者は、Win11 で C ドライブをフォーマットする手順を以下にまとめました。 . 興味のある方はフォローしてみてください! Win10 のアップロード速度が遅い場合の解決策 1. win+R を押して「ファイル名を指定して実行」を呼び出し、「gpedit.msc」と入力して Enter を押します。 2. 管理テンプレートを選択し、[ネットワーク] - [Qos パケット スケジューラ] をクリックし、[制限] をダブルクリックして帯域幅を予約します。 3. 「有効」を選択します。

QQ Musicに歌詞をアップロードする方法 QQ Musicに歌詞をアップロードする方法 Feb 23, 2024 pm 11:45 PM

デジタル時代の到来により、音楽プラットフォームは人々が音楽を入手する主な方法の 1 つになりました。しかし、曲を聴いていると歌詞がないことに気づき、非常に不安になることがあります。曲の内容や感情をより深く理解するために、曲を聴くときに歌詞が表示されることを望む人は多いでしょう。 QQ Music は中国最大の音楽プラットフォームの 1 つとして、ユーザーがより音楽を楽しみ、曲の含意を感じることができるように、ユーザーに歌詞をアップロードする機能も提供しています。 QQ Musicに歌詞をアップロードする方法を紹介します。初め

Kugou に独自の音楽をアップロードする簡単な手順 Kugou に独自の音楽をアップロードする簡単な手順 Mar 25, 2024 pm 10:56 PM

1. Kugou Music を開き、プロフィール写真をクリックします。 2. 右上隅にある設定アイコンをクリックします。 3. [音楽作品をアップロード]をクリックします。 4. [作品アップロード]をクリックします。 5. 曲を選択し、[次へ]をクリックします。 6. 最後に[アップロード]をクリックします。

パソコンのアップロード速度を改善する方法 パソコンのアップロード速度を改善する方法 Jan 15, 2024 pm 06:51 PM

アップロード速度が非常に遅くなりますか?これは、多くの友人がコンピューターにアップロードするときに遭遇する問題だと思います。コンピューターを使用してファイルを転送するときにネットワークが不安定だと、アップロード速度が非常に遅くなります。では、ネットワークのアップロード速度を上げるにはどうすればよいでしょうか?以下では、エディターがコンピューターのアップロード速度が遅いという問題を解決する方法を説明します。ネットワーク速度に関しては、Web ページを開く速度、ダウンロード速度、アップロード速度も非常に重要であることは誰もが知っています。特に一部のユーザーはファイルをネットワーク ディスクにアップロードする必要があることが多いため、アップロード速度が速いと間違いなく節約になります。お金がたくさんあります。時間がなくなりました。アップロード速度が遅い場合はどうすればよいですか?以下では、エディターがコンピューターのアップロード速度が遅い場合の対処方法についての写真とテキストを提供します。コンピューターのアップロード速度が遅いという問題を解決するには、「スタート」-「ファイル名を指定して実行」または「Window キー」をクリックします。

Vue テクノロジー開発における画像のアップロードと圧縮の処理方法 Vue テクノロジー開発における画像のアップロードと圧縮の処理方法 Oct 08, 2023 am 10:58 AM

Vue テクノロジ開発で画像のアップロードと圧縮を処理する方法 最新の Web アプリケーションでは、画像のアップロードは非常に一般的な要件です。ただし、ネットワーク送信とストレージの理由により、オリジナルの高解像度画像を直接アップロードすると、アップロード速度が遅くなり、ストレージ容量が大量に無駄になる可能性があります。したがって、画像のアップロードと圧縮は非常に重要です。 Vue テクノロジー開発では、いくつかの既製のソリューションを使用して画像のアップロードと圧縮を処理できます。 vue-upload-comoneの使い方を紹介します。

uniappに画像圧縮機能を実装する方法 uniappに画像圧縮機能を実装する方法 Jul 06, 2023 pm 05:16 PM

uniapp に画像圧縮機能を実装する方法 1. はじめに 現代社会において、写真は人々の日常生活に欠かせないものとなっています。しかし、携帯電話のカメラ機能の普及や写真の画素数の向上により、写真のファイルサイズも大きくなっています。これにより、携帯電話のメモリが占​​有されるだけでなく、ネットワーク送信中に画像の読み込みに時間がかかります。したがって、画像圧縮は開発者にとって重要なタスクの 1 つになっています。 2. uniapp での画像圧縮 uniapp は、Vue.js をベースとしたクロスプラットフォーム開発フレームワークです。

See all articles