ホームページ > 記事 > ウェブフロントエンド > モバイル画像アップロードの回転と圧縮の問題の解決策
この記事では、モバイル画像アップロードの回転と圧縮の問題の解決策を紹介します。困っている友人は参考にしていただければ幸いです。
まえがき
携帯電話で Web ページの input タグを使用して写真を撮影したり、写真をアップロードしたりすると、一部の携帯電話では画像が 90 度回転する問題には、iPhone および個々の Samsung 製携帯電話が含まれます。この問題は、これらの携帯電話を縦方向に撮影した場合にのみ発生し、横方向に撮影した写真は正常に表示されます。したがって、携帯電話のカメラ角度を取得して写真を回転させることで、この問題を解決できます。
方向
このパラメータはすべての写真で利用できるわけではありませんが、携帯電話で撮影した写真にはこのパラメータがあります。
パラメータ値 | |
---|---|
#時計回りに 90° | |
##反時計回りに 90° | ##8 |
180° | 3 |
パラメーターが 1 の場合、表示は正常です。この水平ショットでは表示は正常です。つまり、Orientation = 1 の携帯電話では、垂直撮影パラメータは 6 です。 | Orientation パラメーターを取得したい場合は、exif.js ライブラリを通じて操作できます。 exif.js は多機能でサイズが大きく、非圧縮前では 30k あり、モバイル ページの読み込みに大きな影響を与えます。そして、方向情報のみを取得する必要があるため、exif.js ライブラリから一部のコードを削除し、コードを数 KB に削減しました。 |
EXIF.getData(file, function() { var Orientation = EXIF.getTag(this, 'Orientation'); });
file は、入力ファイル フォームによってアップロードされたファイルです。アップロードされたファイルは、fileReader.readAsDataURL(file) を通じてプレビューできます。これについてわからない場合は、HTML5 上級シリーズ: ファイルのアップロードとダウンロード
Rotation
を確認してください。回転には、canvas のrotate() メソッドが必要です。 ctx.rotate(angle);
rotate メソッドのパラメータは回転円弧です。角度はラジアンに変換する必要があります: 度 * Math.PI / 180回転の中心点は、デフォルトではキャンバスの開始点、つまり (0, 0) にあります。回転の原理は次のとおりです。
回転概略図
回転後、(0, 0)点からdrawImage()を実行すると、描画位置は左図の可視領域外の90度回転後の位置となります。回転後、座標軸も回転しますので、表示領域に表示したい場合は、このときの始点である(0,0)点をy軸の逆方向に移動する必要があります。は (0, -y ) です。
同様に、-90度回転後の始点は(-x, 0)、180度回転後の始点は(-x, -y)となります。
圧縮
携帯電話で撮影した写真は大きすぎるため、base64 を使用してエンコードされた写真は元の写真よりも大きくなります。圧縮が非常に必要ですので、アップロードしてください。現在の携帯電話のピクセル数は非常に高く、撮影した写真の幅と高さは数千ピクセルなので、キャンバスを使用して写真をレンダリングすると比較的遅くなります。 したがって、最初のステップは、アップロードする写真の幅と高さを制限し、幅または高さが範囲を超えているかどうかを判断し、幅と高さを同じ比率で圧縮することです。 var ratio = width / height;if(imgWidth > imgHeight && imgWidth > xx){
imgWidth = xx;
imgHeight = Math.ceil(xx / ratio);
}else if(imgWidth yy){
imgWidth = Math.ceil(yy * ratio);
imgHeight = yy;
}
2 番目のステップは、canvas.toDataURL() メソッドを使用して写真の品質を圧縮することです。
canvas.toDataURL("image/jpeg", 1);
toDataURL() メソッドは、画像表示を含むデータ URI を返します。 2 つのパラメータを使用します。最初のパラメータは画像形式で、デフォルトは image/png です。 2 番目のパラメータは圧縮品質です。指定された画像形式が image/jpeg または image/webp の場合、画質を 0 ~ 1 から選択できます。
#概要 上記に基づいて、サンプル コードには簡略化された exif.js ライブラリ アドレスが含まれています: file-demoMain コア コードは次のとおりです。 <input><img alt="モバイル画像アップロードの回転と圧縮の問題の解決策" >
<script></script>
<script>
var ipt = document.getElementById('files'),
img = document.getElementById('preview'),
Orientation = null;
ipt.onchange = function () {
var file = ipt.files[0],
reader = new FileReader(),
image = new Image();
if(file){
EXIF.getData(file, function() {
Orientation = EXIF.getTag(this, 'Orientation');
});
reader.onload = function (ev) {
image.src = ev.target.result;
image.onload = function () {
var imgWidth = this.width,
imgHeight = this.height; // 控制上传图片的宽高
if(imgWidth > imgHeight && imgWidth > 750){
imgWidth = 750;
imgHeight = Math.ceil(750 * this.height / this.width);
}else if(imgWidth < imgHeight && imgHeight > 1334){
imgWidth = Math.ceil(1334 * this.width / this.height);
imgHeight = 1334;
}
var canvas = document.createElement("canvas"),
ctx = canvas.getContext('2d');
canvas.width = imgWidth;
canvas.height = imgHeight;
if(Orientation && Orientation != 1){
switch(Orientation){
case 6: // 旋转90度
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate(Math.PI / 2);
// (0,-imgHeight) 从モバイル画像アップロードの回転と圧縮の問題の解決策那里获得的起始点
ctx.drawImage(this, 0, -imgHeight, imgWidth, imgHeight);
break;
case 3: // 旋转180度
ctx.rotate(Math.PI);
ctx.drawImage(this, -imgWidth, -imgHeight, imgWidth, imgHeight);
break;
case 8: // 旋转-90度
canvas.width = imgHeight;
canvas.height = imgWidth;
ctx.rotate(3 * Math.PI / 2);
ctx.drawImage(this, -imgWidth, 0, imgWidth, imgHeight);
break;
}
}else{
ctx.drawImage(this, 0, 0, imgWidth, imgHeight);
}
img.src = canvas.toDataURL("image/jpeg", 0.8);
}
}
reader.readAsDataURL(file);
}
}</script>
概要: 上記がこの記事の全内容です。皆さんの学習に役立つことを願っています。関連チュートリアルの詳細については、JavaScript ビデオ チュートリアル
jQuery ビデオ チュートリアル
、bootstrap チュートリアル
をご覧ください。以上がモバイル画像アップロードの回転と圧縮の問題の解決策の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。