in storage-reverse-image-search/functions/src/common/feature_vectors.ts [32:78]
export async function _loadImageAsTensor(image: string): Promise<tf.Tensor4D> {
const buffer: Uint8Array = await (async () => {
if (isBase64Image(image)) {
return Buffer.from(image, 'base64');
} else {
const [downloaded] = await admin
.storage()
.bucket(config.imgBucket)
.file(image)
.download();
return downloaded;
}
})();
return tf.tidy(() => {
// decodeImage creates a 3D tensor
const decoded = tf.node.decodeImage(buffer, 3) as tf.Tensor3D;
// figure out how to center‐crop to square
const [h, w] = decoded.shape;
let box: [number, number, number, number];
if (w > h) {
// crop the left and right sides to make it square
const crop = (1 - h / w) / 2;
box = [0, crop, 1, 1 - crop];
} else {
// crop the top and bottom sides to make it square
const crop = (1 - w / h) / 2;
box = [crop, 0, 1 - crop, 1];
}
const batched = decoded.expandDims(0) as tf.Tensor4D; // [1,H,W,3]
const resized = tf.image.cropAndResize(
batched,
[box], // boxes: [1,4]
[0], // boxInd: [1]
[config.inputShape, config.inputShape]
) as tf.Tensor4D; // [1,inputShape,inputShape,3]
// clean up the intermediates
decoded.dispose();
batched.dispose();
// return a normalized 4D tensor
return resized.div(255) as tf.Tensor4D;
});
}