html5 canvasによる画像圧縮のサンプルコード
2022-02-01 16:13:52
私は画像のbase64が大きすぎる場合、要求は非常に遅く、深刻な直接タイムアウトになることがわかったので、私はアップロードする前に画像を圧縮することを考え、その後大幅に効率を改善することができますバックグラウンドにアップロードし、ここでいくつかのピットを記録するキャンバス圧縮画像を使用して発生しました。完全なコードは、この記事の最後に与えられます。
最初の落とし穴は、圧縮する際に画像自体の幅と高さを取得せず、600*480の固定幅と固定高さを与えてしまったことです。アバターを修正した際、テスト時にアップロードした画像が小さい画像だったため、圧縮した画像が不完全でほとんど空白になってしまったことが問題で、これは圧縮時に画像の元の幅と高さを考慮していないためです。
2つ目の落とし穴は、1つ目の落とし穴の解決策として、画像が読み込まれた後に(onload)幅と高さを取得してcanvasに代入する方法がありますが、これには画像が非同期に読み込まれるという落とし穴があり、リターン時に、必要な圧縮Base64ではなく未定義が返ってくる可能性があります。ここでの解決策は、新しい Promise を作成し、その結果を resolve() として返し、結果を取得するときに .then() を呼び出すことです。
ナレッジポイント
- canvasのtoDataURL('image/png', 0.9) ; キャンバス画像をbase64に変換します。第1パラメータは画像のタイプ、第2パラメータは画像の解像度を指定します。
- 最大サイズを指定し、画像自体がこのサイズより大きい場合は、最大側をスケーリングし、もう一方を画像のスケーリングに従って設定し、キャンバスに設定する .
miniImage.js
export default async function miniSize(imgData, maxSize = 200*1024){
// const maxSize = 200 * 1024;
if(imgData && imgData.files && imgData.files.size < maxSize) {
return imgData.url;
}else{
console.log('---------------- compressed image -------------------');
const canvas = document.createElement('canvas');
let img = new Image();
img.src = imgData.url;
let ctx = canvas.getContext('2d');
return new Promise((resolve =>{
img.addEventListener('load', function(){
// the original size of the image
let originWidth = this.width;
let originHeight = this.height;
// maximum size limit
let maxWidth = 400, maxHeight = 400;
// target size
let targetWidth = originWidth, targetHeight = originHeight;
// the image size exceeds the 400x400 limit
if (originWidth > maxWidth || originHeight > maxHeight) {
if (originWidth / originHeight > maxWidth / maxHeight) {
// wider, size by width
targetWidth = maxWidth;
targetHeight = Math.round(maxWidth * (originHeight / originWidth));
} else {
targetHeight = maxHeight;
targetWidth = Math.round(maxHeight * (originWidth / originHeight));
}
}
canvas.width = targetWidth;
canvas.height = targetHeight;
ctx.drawImage(img, 0, 0, targetWidth, targetHeight);
let base64 = canvas.toDataURL('image/png', 0.9);
resolve(base64);
}, false);
}))
}
}
呼び出し中。
test.js
onChangeImg = async (files, type, index) => {
let previous = this.props.imagePicker.files;
if(type === "add") {
let result = miniSize(files[files.length-1]);
// use the .then() call to get the result
await result.then(res => {
previous.push({url: res});
});
}else if(type === "remove") {
previous.splice(index,1);
}
await this.props.dispatch({
type: 'imagePicker/saveImage',
payload: {
files: previous
}
})
}
以上、本記事の全内容をご紹介しましたが、皆様の学習のお役に立てれば幸いです。また、Script Houseをより一層応援していただければ幸いです。
関連
-
Html5は、同時に複数のsdkのヒントをサポートする
-
html5で複数ページ通信を行うsharedWorkerのコード例
-
Canvasでイベントを追加する方法を説明する
-
モバイル適応のためのremやviewportの使い方を説明する。
-
h5ページ evokeアプリがインストールされていない場合、ダウンロードにジャンプします(iOS、Android)。
-
HTML5 Canvasタグの解説と基本的な使い方
-
html2canvas.jsを使用してページのスクリーンショットを撮影し、表示またはアップロードするサンプルコード
-
キャンバスの幅と高さの設定に関する問題点
-
HTML5 動画再生プラグイン video.js のご紹介
-
Canvas wave garlandのサンプルコード
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
HTML5ページの要素と属性の分析
-
iframeタグが入れ子になっている問題の解決法
-
html+js マークダウンエディタ効果
-
HTML5 のタッチ イベント(touchstart、touchmove、touchend)の実装
-
Canvasでプログレスバー付きの非閉鎖円を描画する
-
HTML5新フォームコントロールとフォームプロパティのサンプルコード詳細
-
キャンバスラバーバンド線引き塗布方法
-
モバイル版Html5におけるBaidu地図のクリックイベント
-
モバイルでiframeを拡大縮小するサンプルコード
-
モバイル開発 HTML5 ボタンをクリックすると、ページがちらついたり、背景が黒くなったりする問題