もくじ
投稿が遅れた言い訳…
お久しぶりです。C.Cです!
前回記事で「また2週間後に…」とか言っときながら、すでに4ヶ月経ってました(笑)
2023年4月から生活リズムが変わってしまい、なかなか投稿できませんでしたが、
やっと落ち着いてきたのでボチボチ再開してこうかなと思っています!
この記事でわかること
- Node.jsでBase64形式画像からJPEGに変換する方法がわかる
- JPEG画像をFirebase Storageに保存し閲覧用のURLを取得する方法がわかる
前回からの課題の引き継ぎ
4ヶ月前なのでかなり忘れちゃっていたのですが、久しぶりにコードを触ったら案外すんなりと解決できたので記事にしていこうと思います。
課題
- ネットワークにつながっていないときにアプリを起動するとローディングが永遠に終わらない
- FunctionsでBase64から画像データにデコードする。
- Google Admob(広告)を貼り付けるとエラーが出る。
”てがきdeよせがき”とは?
完全無料!オンラインで手書きの寄せ書きを作成できるスマホアプリ
iOS、Android共に公開中!
成果報告
状況のおさらい
なにせ4ヶ月ぶりにコードに触ったのでフェイズが分からなくなってしまいました(汗)
- Appleからローディングが終わらないと指摘を受けた
- Firebaseとの通信においてTimeOutを設定していなかったのが原因とわかった
- TimeOutを設定したいがFirebaseとのやり取りが複雑でうまく設定するのが難しい
- Firebaseとデバイスのやり取りを1回だけにするためにFunctionsに機能をまとめようと考えた
- デバイスからFunctionsに画像をBase64形式で渡すことができた
- Funcions内で受け取ったBase64画像をjpegに変換ができない(←前回終了時点がココ)
- jpegに変換できたらFireStorageに保存しURLを取得する
- URL情報とや台紙名などをまとめてFirestoreに保存する
今回は6〜8番を解決した方法になります。
Cloud Funcions内でBase64画像をjpegに変換する
Functionsに渡ってきたBase64をBuffer形式に変換、その後sharpメソッドを使用することでJpegに変換することができました。
exports.createYosegaki = functions
.region("asia-northeast1")
.https.onRequest(async (request, response) => {
// ↓request.body.params.YosegakiImageに含まれるBase64形式の寄せ書き画像をBuffer形式に変換しています。
const YosegakiBuffer = Buffer.from(
request.body.params.YosegakiImage,
"base64"
);
// ↓アイコン画像も同様にBuffer形式に変換します。
const IconBuffer = Buffer.from(request.body.params.faceImage, "base64");
// 寄せ書き画像をJpegの変換します。変数にYosegakiJpegにはBuffer形式のJpegが入ります。
const YosegakiJpeg = await sharp(YosegakiBuffer)
.jpeg()
.toBuffer()
.then((outputBuffer) => {
return outputBuffer;
})
.catch((err) => {
console.error(err);
});
// ↓アイコン画像も同様にJpegに変換します。
const iconJpeg = await sharp(IconBuffer)
.jpeg()
.toBuffer()
.then((outputBuffer) => {
return outputBuffer;
})
.catch((err) => {
// エラーが発生した場合の処理
console.error(err);
});
})
画像をStorageに保管しURLを取得する
getSignedUrlメソッドでURLを取得しています。コンフィグはもっとうまく設定すれば閲覧期間を1年程度にできますがこのままでも問題にはならないでしょう。
//寄せ書き画像の保存場所
const Yosegakifile = bucket.file(`…/yosegakiImage.jpg`);
// 顔画像の保存場所
const Iconfile = bucket.file(`…/iconImage.jpg`);
//コンフィグの設定 一応画像は100年後まで読み込み可能(笑)
const config = {
action: "read",
expires: "01-01-2123",
};
// getSignedUrlにconfigを引数としてURLを取得 変数mediaUrlはおまじないみたいなもの覚えなくていい
const Yres = await Yosegakifile.save(YosegakiJpeg)
.then(async (res) => {
const YosegakiURL = await Yosegakifile.getSignedUrl(config).then(
(signedURLs) => {
const mediaUrl = `https://firebasestorage.googleapis.com/v0/b/${
bucket.name
}/o/${encodeURIComponent(Yosegakifile.name)}?alt=media&token=${
signedURLs[0]
}`;
return mediaUrl;
}
);
return YosegakiURL;
})
.catch((err) => {
console.log("YosegakiFileURL_Error", err);
});
// 当然アイコン画像も同様にURLを取得する
const Ires = await Iconfile.save(faceJpeg)
.then(async (res) => {
const IconURL = await Iconfile.getSignedUrl(config).then(
(signedURLs) => {
const mediaUrl = `https://firebasestorage.googleapis.com/v0/b/${
bucket.name
}/o/${encodeURIComponent(Iconfile.name)}?alt=media&token=${
signedURLs[0]
}`;
return mediaUrl;
}
);
return IconURL;
})
.catch((err) => {});
Firestoreに必要な情報を保存する
ココは簡単♪
// Firestoreに登録する
const db = admin.firestore();
const ref = db
.collection(`…`)
ref
.add({
createdDate: new Date(),
iconImageURL: Ires,
name: request.body.params.name,
yosegakiImageURL: Yres,
})
.then(() => {
response.status("200").send("success");
})
.catch((err) => {
console.log(err);
});
まとめ
4ヶ月前はFuncions内でBase64→Jpeg変換にめちゃくちゃ手こずってたのですが、改めてやってみると結構簡単でしたね♪
今は有給消化中でストレスが少ないのでアプリ開発も集中して取り組めている気がします。
次回の課題
課題
- Google Admob(広告)を貼り付けるとエラーが出る。
次回は広告の貼り付けです。EXPO Admob ads復活しないかなぁ…