HTML5画像圧縮アップロード機能を徹底分析
以下のエディターは、HTML5 に実装された画像圧縮アップロード機能について詳しく説明します。編集者がとても良いと思ったので、皆さんにもシェアしたいと思います。私も参考にしたいので、編集者と一緒に見てください
前の記事で、モバイル端末での写真のアップロードについて触れましたが、現在でもトラフィックが非常に高価であり、モバイルのピクセルも高価であることはわかっています。携帯電話の高さもどんどん高くなってきているので、写真を撮るのは簡単です。怪我をするわけにはいきません。クライアントは画像を簡単に圧縮してアップロードできますが、アプリケーションは依然としてブラウザで開かれる可能性があります。画像圧縮はどうすればよいでしょうか。 PC 上での以前の開発思想の影響で、Nima js にはファイルの操作や画像の圧縮を行う権限がありません。それができない場合は、クライアントが修正できます。ただ言えるのは、まだ少し混乱しているということだけです。 HTML5の影響で、フロントエンドでできることはどんどん増え、開発される機能もどんどん高くなっています、H5万歳!これもフロントエンドの魅力です。過去に不可能だったことが、今も将来も不可能になるわけではありません。頑張れ!
jsで画像を圧縮するには? ? ?最初は無意識のうちに実現不可能だと感じていましたが、後で情報を読んで調べてみると、実現可能であることがわかりました。始めよう!
まず、H5 より前のアップロード方法について説明します。私たちは通常、プラグイン、フラッシュ、または単にファイル形式を使用していたので、それほど心配する必要はありませんでした。
私が H5 を取得して以来、上司は私の成長を心配しなくなりました。
前回の記事では、画像のアップロードに FileReader と FormData が使用されると述べましたが、実際には、基本的にこの 2 つを使用して画像をプレビューしたりアップロードしたりできます。 画像圧縮を実現するには、canvas を使用する必要があります。はい、canvas です。
一般的なアイデアは次のとおりです:
1. 画像とキャンバスを作成します
XML/HTML コードコンテンツをクリップボードにコピーします
2. FileReader を介して入力で選択された画像アドレスを取得し、それを新しく作成された画像オブジェクトに割り当て、画像オブジェクトをキャンバスにスローします。
XML/HTMLコードコンテンツをクリップボードにコピーします
var image = new Image(), canvas = document.createElement("canvas"), ctx = canvas.getContext('2d');
ログイン後にコピー
ここで、キャンバスが画像をキャンバスに描画するときに、サイズを決定する必要があることに注意してください次のように、drawImage のパラメータを設定します:
XML/HTML コードコンテンツをクリップボードにコピーします
void ctx.drawImage(image, sx, sy, sWidth , sHeight, dx, dy, dWidth, dHeight);
<span style="max-width:90%">dx<code><span style="font-family:NSimsun">dx</span>
源图像的左上角在目标canvas上 X 轴的位置。
<span style="font-family:NSimsun">dy</span>
源图像的左上角在目标canvas上 Y 轴的位置。
<span style="font-family:NSimsun">dWidth</span>
在目标canvas上绘制图像的宽度。 允许对绘制的图像进行缩放。 如果不说明, 在绘制时图片宽度不会缩放。
<span style="font-family:NSimsun">dHeight</span>
在目标canvas上绘制图像的高度。 允许对绘制的图像进行缩放。 如果不说明, 在绘制时图片高度不会缩放。
<span style="font-family:NSimsun">sx</span>
需要绘制到目标上下文中的,源图像的矩形选择框的左上角 X 坐标。
<span style="font-family:NSimsun">sy</span>
需要绘制到目标上下文中的,源图像的矩形选择框的左上角 Y 坐标。
<span style="font-family:NSimsun">sWidth</span>
需要绘制到目标上下文中的,源图像的矩形选择框的宽度。如果不说明,整个矩形从坐标的sx和sy开始,到图像的右下角结束。
<span style="font-family:NSimsun">sHeight</span>
の左上隅の位置ターゲット キャンバスの X 軸上のソース イメージ。
<span style="font-family:NSimsun">dy</strong>
<span style="font-family:NSimsun">dWidth</span>
ターゲットキャンバスに描画される画像の幅。 描画した画像の拡大縮小を可能にします。 指定しない場合、描画時にイメージの幅は拡大縮小されません。
<span style="font-family:NSimsun">dHeight</p>
🎜 ターゲットキャンバスに描画される画像の高さ。描画した画像の拡大縮小を可能にします。 指定しない場合、描画時にイメージの高さは拡大縮小されません。 🎜🎜🎜<span style="font-family:NSimsun">sx🎜
🎜 は、ターゲット内のソース画像の長方形の選択ボックスの左上隅の X 座標に描画される必要がありますコンテクスト。 🎜🎜🎜<span style="font-family:NSimsun">sy🎜
🎜 は、ターゲット内のソース画像の長方形の選択ボックスの左上隅の Y 座標に描画される必要がありますコンテクスト。 🎜🎜🎜<span style="font-family:NSimsun">sWidth🎜
🎜 ターゲット コンテキストに描画する必要があるソース イメージの長方形の選択ボックスの幅。指定しない場合、長方形全体は座標 sx と sy から始まり、画像の右下隅で終わります。 🎜🎜🎜<span style="font-family:NSimsun">sHeight🎜
🎜 ターゲット コンテキストに描画する必要があるソース イメージの長方形の選択ボックスの高さ。 🎜🎜🎜完全な画像をアップロードするには、dx、dy を 0 に設定し、dWidth と dHeight を元の画像の幅と高さに設定する必要があります。これが、画像オブジェクトがダウンロードされて元のサイズになるまで待つ必要がある理由です。これは重要です。 🎜🎜🎜🎜🎜3. 写真のアップロード🎜🎜🎜🎜🎜🎜
XML/HTML Code复制内容到剪贴板
function fileUpload() { var data = canvas.toDataURL("image/jpeg", quality); //dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了 datadata = data.split(',')[1]; data = window.atob(data); var ia = new Uint8Array(data.length); for (var i = 0; i < data.length; i++) { ia[i] = data.charCodeAt(i); }; //canvas.toDataURL 返回的默认格式就是 image/png var blob = new Blob([ia], { type: "image/jpeg" }); var fd = new FormData(); fd.append('myFile', blob); var xhr = new XMLHttpRequest(); xhr.addEventListener("load", opts.success, false); xhr.addEventListener("error", opts.error, false); xhr.open("POST", opts.url); xhr.send(fd); }
ログイン後にコピー
这里用的关键方法是canvas.toDataURL
XML/HTML Code复制内容到剪贴板
canvas.toDataURL(type, encoderOptions);
官方的说明是The <span style="font-family:NSimsun">HTMLCanvasElement.toDataURL()</span>
method returns a data URI containing a representation of the image in the format specified by the <span style="font-family:NSimsun">type</span>
parameter (defaults to PNG). The returned image is in a resolution of 96 dpi.实际上就是读取canvas画布上图片的数据。其默认是png格式,如果第一个参数type是image/jpeg的话,第二个参数encoderOptions就可以用来设置图片的压缩质量,经过测试,如果是png格式,100%的宽高经过该方法还有可能使图片变大~~~~适得其反,所以我们可以在canvas.drawImage的时候适当设置sWidth和sHeight,比如同比例缩小1.5倍等,图片质量其实并不太影响查看,尤其对尺寸比较大的图片来说。
上面还有比较陌生的方法atob,其作用是做解码,因为图片格式的base64.
XML/HTML Code复制内容到剪贴板
var encodedData = window.btoa("Hello, world"); // encode a string
var decodedData = window.atob(encodedData); // decode the string
该方法解码出来可能是一堆乱码,Uint8Array返回的是8进制整型数组。
Blob是存储二进制文件的容器,典型的Blob对象是一个图片或者声音文件,其默认是PNG格式。
XML/HTML Code复制内容到剪贴板
var blob = new Blob([ia], {
type: "image/jpeg"
});
最后通过ajax将Blob对象发送到server即可。
整个流程大致如上,但是~~~实现以后测试跑来说:“你不是说图片压缩了吗,为什么图片还是上传那么慢!”,哥拿起手机对妹纸演示了一下,明明很快嘛,于是反道“是你手机不行或者网络不好吧,你下载图片看明明变小了,比之前肯定快,你看我秒传”。呵呵,说归说,还是偷偷检查代码,在浏览器中打时间log,对比没压缩之前的,尼玛!!!居然才快了几百毫秒!!折腾了半天,之前的代码也重构了,玩我呢。
细心的大神看了上面的代码估计能猜出问题在哪,没错,获取本地图片长宽尺寸的时候出了问题。
我去,获取本地4M大小的图片尺寸花了3174ms!!,图片越大时间也越久~
JavaScript Code复制内容到剪贴板
image.onload = function() { var w = image.naturalWidth, h = image.naturalHeight; canvas.width = w / 1.5; canvas.height = h / 1.5; ctx.drawImage(image, 0, 0, w, h, 0, 0, w / 1.5, h / 1.5); Upload.fileUpload(type); };
ログイン後にコピー
浏览器在本地取图片的时候是没法直接像file.size一样获取其长宽的,只能通过FileReader拿到内容后赋值给新建的image对象,新建的image对象下载需要时间!怎么破?不就是获取本地图片的尺寸吗,难道没有别的办法了?
于是想到了之前研究过的快速获取图片长宽的博文,点击进入 ,demo地址:http://jsbin.com/jivugadure/edit?html,js,output,定时去查询图片加载过程中的高度或者宽度,不用等整个图片加载完毕。
测了下,还是不行,因为定时查询这种方法对常规的server返回的图片有作用,这里图片地址是base64,貌似时间还更久了~哭。
小结一下:
1、用HTML5来压缩图片上传是可行的,在移动端我们不用依赖客户端或者插件,目前主流浏览器支持程度已经很高了。
2、压缩图片一方面是想减少用户上传等待的时间,另外也减少用户为此牺牲的流量,从整体时间来看,因为获取图片尺寸导致多一次下载需要耗时,其实压不压缩时间差别并不是特别大。除非大神们找到合适的方法能够直接获取图片的尺寸,麻烦也告知我一声,万分感谢;
3、既然时间成本差不多,但是我们压缩了图片,减少了图片的大小,减少了流量的消耗,存储空间以及下次获取该图片的时间,所以还是值得的。
补充源代码:
JavaScript Code复制内容到剪贴板
(function($) { $.extend($.fn, { fileUpload: function(opts) { this.each(function() { var $self = $(this); var quality = opts.quality ? opts.quality / 100 : 0.2; var dom = { "fileToUpload": $self.find(".fileToUpload"), "thumb": $self.find(".thumb"), "progress": $self.find(".upload-progress") }; var image = new Image(), canvas = document.createElement("canvas"), ctx = canvas.getContext('2d'); var funs = { setImageUrl: function(url) { image.src = url; }, bindEvent: function() { console.log(dom.fileToUpload) dom.fileToUpload.on("change", function() { funs.fileSelect(this); }); }, fileSelect: function(obj) { var file = obj.files[0]; var reader = new FileReader(); reader.onload = function() { var url = reader.result; funs.setImageUrl(url); dom.thumb.html(image); }; image.onload = function() { var w = image.naturalWidth, h = image.naturalHeight; canvas.width = w; canvas.height = h; ctx.drawImage(image, 0, 0, w, h, 0, 0, w, h); funs.fileUpload(); }; reader.readAsDataURL(file); }, fileUpload: function() { var data = canvas.toDataURL("image/jpeg", quality); //dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了 data = data.split(',')[1]; data = window.atob(data); var ia = new Uint8Array(data.length); for (var i = 0; i < data.length; i++) { ia[i] = data.charCodeAt(i); }; //canvas.toDataURL 返回的默认格式就是 image/png var blob = new Blob([ia], { type: "image/jpeg" }); var fd = new FormData(); fd.append('myFile', blob); var xhr = new XMLHttpRequest(); xhr.addEventListener("load", opts.success, false); xhr.addEventListener("error", opts.error, false); xhr.open("POST", opts.url); xhr.send(fd); } }; funs.bindEvent(); }); } }); })(Zepto);
ログイン後にコピー
调用方式:
JavaScript Code复制内容到剪贴板
$(".fileUpload").fileUpload({ "url": "savetofile.php", "file": "myFile", "success":function(evt){ console.log(evt.target.responseText) } });
ログイン後にコピー
希望大家能找到更好的办法,多多交流!感谢!
以上がHTML5画像圧縮アップロード機能を徹底分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

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

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

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

ホットトピック











HTML の表の境界線に関するガイド。ここでは、HTML でのテーブルの境界線の例を示しながら、テーブル境界線を定義する複数の方法について説明します。

これは、HTML でのネストされたテーブルのガイドです。ここでは、テーブル内にテーブルを作成する方法をそれぞれの例とともに説明します。

HTML マージン左のガイド。ここでは、HTML margin-left の概要とその例、およびそのコード実装について説明します。

HTML テーブル レイアウトのガイド。ここでは、HTML テーブル レイアウトの値と例および出力について詳しく説明します。

HTML 入力プレースホルダーのガイド。ここでは、コードと出力とともに HTML 入力プレースホルダーの例について説明します。

HTML でのテキストの移動に関するガイド。ここでは、概要、マーキー タグが構文でどのように機能するか、および実装例について説明します。

HTML オンクリック ボタンのガイド。ここでは、それらの紹介、動作、例、およびさまざまなイベントでの onclick イベントについてそれぞれ説明します。
