Skip to content

Commit 43df2e0

Browse files
committed
Crop character avatar to rectangle
We always show it as circle anyway, so we can save some storage this way.
1 parent ed30009 commit 43df2e0

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

functions/src/functions/changeCharacterAvatar.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as sharp from "sharp";
77
import * as t from "io-ts";
88
import {UploadResponse} from "@google-cloud/storage/build/src/bucket";
99
import {Bucket} from "@google-cloud/storage";
10+
import {Sharp} from "sharp";
1011

1112
const imageSize = 500
1213

@@ -49,7 +50,7 @@ export const changeCharacterAvatar = functions.https.onCall(async (data, context
4950

5051
const tempFile = await file();
5152

52-
await sharp(Buffer.from(imageData, "base64"))
53+
await (await cropToRectangle(sharp(Buffer.from(imageData, "base64"))))
5354
.resize(imageSize, imageSize, {fit: "outside"})
5455
.webp()
5556
.toFile(tempFile.path);
@@ -81,6 +82,27 @@ export const changeCharacterAvatar = functions.https.onCall(async (data, context
8182
};
8283
});
8384

85+
const cropToRectangle = async (image: Sharp): Promise<Sharp> => {
86+
const metadata = await image.metadata();
87+
const width = metadata.width;
88+
const height = metadata.height;
89+
90+
if (width == undefined || height == undefined) {
91+
console.error("Could not read image width and height");
92+
93+
return image;
94+
}
95+
96+
const size = Math.min(width, height);
97+
98+
return image.extract({
99+
top: Math.round((height - size) / 2),
100+
left: Math.round((width - size) / 2),
101+
width: size,
102+
height: size,
103+
})
104+
}
105+
84106
const generateAvatarUrl = (response: UploadResponse, bucket: Bucket): string => {
85107
if ("FIREBASE_STORAGE_EMULATOR_HOST" in process.env) {
86108
return response[1].mediaLink;

0 commit comments

Comments
 (0)