JSで画像を扱うときのメモ
はじめに
jsで画像を扱おうと思い調べ直したのでまとめる。
TL;DR.
準備
Reactで試すのでプロジェクト作るところから。
$ npx create-react-app image-sample --template typescript
画像を読み込む
input要素の変更イベント見てそこから取ればOK。
const App: React.VFC = () => {
return (
<label>
画像:
<input type="file" accept="image/png, image/jpeg" onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
console.log('e.target.files: ', e.target.files);
}}/>
</label>
);
}
画像の値を取る
上記の通り画像のデータはevent.target.files[N]
の中にある。
取れるパラメータについては下記参照。
File - Web API | MDN
const App: React.VFC = () => {
return (
<label>
画像:
<input type="file" accept="image/png, image/jpeg" onChange={async (e: React.ChangeEvent<HTMLInputElement>) => {
// filesはnullable
if (e.target.files == null) {
return;
}
console.log(e.target.files[0]);
console.log('file name: ', e.target.files[0].name);
console.log('file size: ', e.target.files[0].size);
console.log('file type: ', e.target.files[0].type);
console.log('ladtmodified: ', e.target.files[0].lastModified);
// lastModifedDataはjs的には取得できるがtsで型定義がないためエラー履く
// @ts-ignore
console.log('ladtmodifiedDate: ', e.target.files[0].lastModifiedDate);
}}/>
</label>
);
}
画像をbase64形式に変換する
バックエンドAPIに画像のデータを送るときもあると思う。
画像のデータの中身を読み取るにはFileReaderを使う。
画像を読み込んだあとになにかしたい場合、FileReader.onloadを上書きすればOK。
読み込む形式によってメソッドが変わるが、base64の場合はFileReaer.readAsDataURL
を使う。
const App: React.VFC = () => {
return (
<label>
画像:
<input type="file" accept="image/png, image/jpeg" onChange={async (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files === null) {
return;
}
//
const reader = new FileReader();
reader.onload = (e: ProgressEvent<FileReader>) => {
console.log('e.target.result: ', e.target?.result);
}
reader.readAsDataURL(e.target.files[0]);
}}/>
</label>
);
}
onloadを上書きしても良いが、loadイベントをハンドリングしても同じ事ができる。
const App: React.VFC = () => {
return (
<label>
画像:
<input type="file" accept="image/png, image/jpeg" onChange={async (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files === null) {
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event: ProgressEvent<FileReader>) => {
// どちらでも取得可能
console.log(event.target?.result);
console.log(reader.result);
});
reader.readAsDataURL(e.target.files[0]);
}}/>
</label>
);
}
注意
readAsDataURL
で取得したbase64データはデータURL形式
のためそのままではbase64文字列のみを取得できない。
データ形式はdata:[<mediatype>][;base64],<data>
のため,
で区切って取得すれば良い。
reader.onload = (e: ProgressEvent<FileReader>) => {
if (typeof e.target?.result === 'string') {
// ,より後ろがbase64文字列なので区切って2番目を取得
console.log('base64文字列:', e.target.result.split(',')[1]);
}
}
まとめ
今回はFile周りについて改めてまとめた。
callback内で結果を取る必要があるため取得した値を使うにはひと工夫いりそう。
(callback内で値を使う処理をするか、reactであればstateに入れて外で使うなど)
これくらいであればlibraryを使わなくてもできることがわかったので、jsだけでできることはできるだけjsで完結させていきたい。