Browser Image Compressionで画像をアップロード前に圧縮する[Javascript]
どうもfujiharaです。本日は画像をアップロード前に圧縮できる BrowserImageCompressionをご紹介します。
インストール
npm install browser-image-compression --save
or
yarn add browser-image-compression
コード
以下が簡単な確認用コードになります。(react-create-appで作成)
import './App.css';
import { useState } from 'react';
import imageCompression from 'browser-image-compression';
function App() {
const [image_url, setImageUrl] = useState('');
const compressOption = {
maxSizeMB: 1,
maxWidthOrHeight: 1024
};
return (
<div className="App">
<form onSubmit={async (e) => {
e.preventDefault();
const form = new FormData(e.target);
const postForm = new FormData();
const file = form.get('image');
const compressFile = await imageCompression(file ,compressOption);
postForm.append('image', compressFile, file.name);
alert(`default_size: ${file.size} \n compressed_size: ${compressFile.size}`);
// fetch postForm
}}
>
<input name="image" accept="image/jpeg,image/png" type="file"
onChange={async (e) => {
setImageUrl('');
if (!e.target.files[0]) {
return;
}
const img = e.target.files[0];
try {
const compressFile = await imageCompression(img, compressOption);
const url = await imageCompression.getDataUrlFromFile(compressFile);
setImageUrl(url);
} catch (error) {
console.log(error);
}
}}
/>
{image_url && <figure>
<img src={image_url} alt=''/>
</figure>
}
<div className='mod-button'>
<button type="submit">送信</button>
</div>
</form>
</div>
);
}
export defau< App;
説明
ファイルを選択したときと、送信ボタンを押した時に圧縮処理が入っています。 圧縮時のオプションですが、最大サイズを1Mにし最大縦横を1024pxにしました。 まずonChange箇所です。inputが変わった時にまず imgタグに使用するsrcの初期化を行い、ファイルが選択されていない場合は終了。選択されている場合は 圧縮しURLを取得するとimgタグのsrcに入るようしています。 (表示された画像は圧縮後のもの)
onChange={async (e) => {
setImageUrl('');
if (!e.target.files[0]) {
return;
}
const img = e.target.files[0];
try {
const compressFile = await imageCompression(img, compressOption);
const url = await imageCompression.getDataUrlFromFile(compressFile);
setImageUrl(url);
} catch (error) {
console.log(error);
}
}}
次にformのsubmit時です。onChangeの時と同様に、通常ファイルを取得・圧縮して、 FormDataにアタッチしています。 (ファイルオブジェクトをステートに持ちたくないため、onChangeの時と圧縮処理が2重になっています) 今回は送信せずに圧縮前後でのファイルサイズをalertするだけになっています。
e.preventDefault();
const form = new FormData(e.target);
const postForm = new FormData();
const file = form.get('image');
const compressFile = await imageCompression(file ,compressOption);
postForm.append('image', compressFile, file.name);
alert(`default_size: ${file.size} \n compressed_size: ${compressFile.size}`);
//fetch data....
まとめ
いかがでしたでしょうか、これでユーザーがスマホの場合などに送信するパケットを抑えることができます。 今回設定したオプションは最大ファイルサイズ、縦横幅(比率を保ったまま圧縮)です。 他のオプションもあるので公式サイトで確認してみてください。