解決すること
フォームからGAS経由で画像をアップロードするとファイルが破損して開けないという状況を回避します。
(以下がその情報の記事)
https://qiita.com/TechnoKuRo/items/442d5d9ace73edcb4be7
https://auto-worker.com/blog/?p=865
やりたいこと
- 入力フォームから画像を選択
- JSで画像データをGASの関数に渡す
- GASの関数がGoogle Driveに保存する
実践
本記事では、フォームのコードについては割愛しています。
今回は画像を保存したいので、フォームではimage/*
のみ許容するようにしました。
ちなみに私はVuetifyのFile inputコンポーネントを最近使用しました。
1. JS
入力フォームからは以下のような関数を呼ぶようにしておきます。
function saveImage() {
google.script.run.withSuccessHandler(
(result) => {
//resultにはGASの戻り値が入ります(今回の例だとtrue)
// Net state changed from IDLE to BUSY (処理中)
// Net state changed from BUSY to IDLE (完了)
// とログが出力されますので、完了後に何かしたい場合は
// ここにその処理を記載します。
}
).saveGdrive(img);
};
2. GAS
JSから渡されたimgは、
data:image/png;base64,xxxxxxxxxxxxxxxxxxxxxx...
というbase64にエンコードされたデータであることを前提としています。
頭の部分に画像の形式があり、xxxxx...の部分が実際の画像データのバッファが含まれています。
下記のソースでは、以下の手順を踏んでいます。
- 頭の部分のデータから、拡張子とMimeTypeを把握する。
- 把握後に頭の部分を取り除いて、画像のバッファデータだけにする。
- GASのUtilitiesサービスを使用して、一旦Decode、再度Blobに変換する。
- Google Driveに保存する。
function saveGdrive(img) {
// IDは、https://drive.google.com/drive/folders/{この部分}
const GDRIVE_FOLDER_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const gdrive = DriveApp.getFolderById(GDRIVE_FOLDER_ID);
const mimeType = {
'bmp': MimeType.BMP,
'gif': MimeType.GIF,
'jpeg': MimeType.JPEG,
'png': MimeType.PNG,
'svg+xml': MimeType.SVG,
};
const extension = {
'bmp': 'bmp',
'gif': 'gif',
'jpeg': 'jpg',
'png': 'png',
'svg+xml': 'svg',
};
const ext = img.slice(img.indexOf('/') + 1, img.indexOf(';')); // 拡張子
const filename = "TEST" + '.' + extension[ext]; // ファイル名
img = img.replace(/\S*,/, ''); // Buffer取得
img = Utilities.base64Decode(img); // 一旦Decode
img = Utilities.newBlob(img, mimeType[ext], filename); // Blobに変換
gdrive.createFile(img); // Google Driveに保存
return true;
}
これで無事画像がGoogle Driveに保存されます。
さいごに
今回紹介したコードには、細かなエラー処理を含んでおりませんので、
参考にする際はお気をつけ下さい。
Apps Scriptは2020~2021の境目あたりにエディタが使いやすくなったので、
決してChrome V8ランタイムはオフにせず、
素敵なコーディングライフ(?)を送りましょう!