始めに
サーバーに画像をアップロードするためにinputタグを使って以下のような感じでアップロードしていました。
ファイルアップロード
const elInput = document.getElementById('file');
const file = elInput.files[0];
// FileインスタンスをFormDataに含めて送信
const formData = new FormData();
formData.append('file', file);
axios.request({
method: 'post',
url: 'api/upload',
data: formData,
});
基本的にはこれで問題ないのですが、画像を含むその他の情報もまとめてコピーする機能が欲しいと言われた際に、そのままでは上手くできないなと思いました。
サーバーから取得した画像を上手くFileに変換できれば同じようにFormDataを使って送信すれば良いのですが、それを調べるのに少し時間がかかりました(そもそもできるのかも分かりませんでしたし)。
結論としてはできましたので、そのやり方を備忘録として残したいと思います。
サーバーにある画像をFileに変換する方法
まず始めに画像をバイナリとして取得する必要があります。その次にBlobに変換し、最後Fileに変換することができます。
Fileに変換できればあとは最初に書いたアップロード方法でアップすれば終了です。
画像をバイナリで取得し、Fileに変換する方法
// バイナリで取得する
const response = await axios.request({
method: 'get',
responseType: 'arraybuffer',
url: 'image url',
});
// レスポンスヘッダーからimage/pngなどのファイル形式を受け取れるので取得する
const fileType = response.headers['content-type'];
// バイナリ -> Blob -> Fileと変換
const blob = new Blob([response.data], { type: fileType });
const file = new File([blob], 'copy filename', { type: fileType });
終わりに
以上がサーバーにある画像をFileに変換して再アップロード(コピー)する方法でした。APIから取得したデータもFileに変換できるというのはちょっと驚きでした。バイナリの扱いは結構難しいですが、しっかり学べば結構なんでもできそうだなぁと感じました。