export async function _loadImageAsTensor()

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;
  });
}