ホームページ > 記事 > ウェブフロントエンド > モバイル画像のアップロード、回転、圧縮のためのソリューション
携帯電話で Web ページの入力タグを介して写真を撮影しアップロードすると、iPhone や一部の Samsung 製携帯電話など、一部の携帯電話では写真が 90 度回転するという問題が発生します。この問題は、これらの携帯電話を縦方向に撮影した場合にのみ発生し、横方向に撮影した写真は正常に表示されます。したがって、携帯電話のカメラ角度を取得して写真を回転させることで、この問題を解決できます。
すべての写真にこのパラメータがあるわけではありませんが、携帯電話で撮影した写真にはこのパラメータがあります。
回転角度 | パラメータ値 |
---|---|
0° | 1 |
時計回り90° | 6 |
反時計回り90° | 8 |
180° | 3 |
パラメータが 1 の場合、ディスプレイは通常です。その後、これらの水平ショットではディスプレイが通常です。つまり、Orientation = 1 の携帯電話では、垂直ショットのパラメータは 6 です。
Orientation パラメーターを取得したい場合は、exif.js ライブラリを通じて操作できます。 exif.js は多くの機能を備えており、非圧縮前では 30k と非常に大きく、モバイル ページの読み込みに大きな影響を与えます。そして、方向情報のみを取得する必要があるため、exif.js ライブラリから一部のコードを削除し、コードを数 KB に削減しました。
exif.js は Orientation を取得します:
EXIF.getData(file, function() { var Orientation = EXIF.getTag(this, 'Orientation');});
file は、入力ファイル フォームによってアップロードされたファイルです。アップロードされたファイルは、fileReader.readAsDataURL(file) を通じてプレビューできます。これについてわからない場合は、次の点を確認してください。 HTML5 上級シリーズ: ファイルのアップロードとダウンロード
Rotation では、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 < imgHeight && imgHeight > 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-demo
主要なコア コードは次のとおりです:
<input type="file" id="files" ><img src="blank.gif" id="preview" alt="モバイル画像のアップロード、回転、圧縮のためのソリューション" > <script src="small-exif.js?1.1.11"></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>
以上がモバイル画像のアップロード、回転、圧縮のためのソリューションの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。