Image Processing using Google Cloud Functions

dheerajbhadani

dheerajbhadani

Posted on August 2, 2020

Image Processing using Google Cloud Functions

In this blog I am going to share how to create a microservice using Google Cloud Function. The objective is to reformat image when it gets uploaded to Google Cloud Storage bucket.

Setup

I am using Google cloud shell to run all the command. For details about the Google cloud shell please follow official documentation.

Solution

According to Google,

Cloud Storage provides worldwide, highly durable object storage that scales to exabytes of data. You can access data instantly from any storage class, integrate storage into your applications with a single unified API, and easily optimize price and performance.

Step 1: Create two GCS buckets using gcloud commands. One for source image sequence and another for processed image sequence.

export SOURCE_BUCKET_NAME=$DEVSHELL_PROJECT_ID-source
export PROCESSED_BUCKET_NAME=$DEVSHELL_PROJECT_ID-processed

echo "Creating source bucket: gs://$SOURCE_BUCKET_NAME"
gsutil mb gs://$SOURCE_BUCKET_NAME

echo "Creating processed bucket: gs://$PROCESSED_BUCKET_NAME"
gsutil mb gs://$PROCESSED_BUCKET_NAME

Step 2: Create a Google Cloud Function using gcloud.

Cloud Functions is Google Cloud’s event-driven serverless compute platform. Run your code locally or in the cloud without having to provision servers. Go from code to deploy with continuous delivery and monitoring tools. Cloud Functions scales up or down, so you pay only for compute resources you use. Easily create end-to-end complex development scenarios by connecting with existing Google Cloud or third-party services.

Now, we will create a google cloud function which will get triggered when the image gets uploaded to the storage.

Cloud function’s entry point must be defined in a Python source file called main.py Details on Python runtime can be found here. Add the following function to main.py.

import os
import cv2
import numpy as np
from google.cloud import storage
from tempfile import NamedTemporaryFile


def reformat_image(event, context):
    """Triggered by a change to a Cloud Storage bucket.
    Args:
         event (dict): Event payload.
         context (google.cloud.functions.Context): Metadata for the event.
    """
    file = event

    client = storage.Client()
    source_bucket = client.get_bucket(file['bucket'])
    source_blob = source_bucket.get_blob(file['name'])

    image = np.asarray(bytearray(source_blob.download_as_string()), dtype="uint8")
    image = cv2.imdecode(image, cv2.IMREAD_UNCHANGED)

    scale_percent = 50  # percent of original size
    width = int(image.shape[1] * scale_percent / 100)
    height = int(image.shape[0] * scale_percent / 100)
    dim = (width, height)

    # resize image
    resized = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)

    with NamedTemporaryFile() as temp:
        # Extract name to the temp file
        temp_file = "".join([str(temp.name), file['name']])

        # Save image to temp file
        cv2.imwrite(temp_file, resized)

        # Uploading the temp image file to the bucket
        dest_filename = file['name']
        dest_bucket_name = os.environ.get('PROCESSED_BUCKET_NAME', 'Specified environment variable is not set.')
        dest_bucket = client.get_bucket(dest_bucket_name)
        dest_blob = dest_bucket.blob(dest_filename)
        dest_blob.upload_from_filename(temp_file)

Add requirements.txt with the following content:

opencv-python==4.2.0.34
numpy==1.18.2
google-cloud-storage==1.27.0

Step 3: Deploy function

gcloud functions deploy reformat_image --set-env-vars PROCESSED_BUCKET_NAME=$PROCESSED_BUCKET_NAME --runtime python37 --trigger-resource $SOURCE_BUCKET_NAME --trigger-event google.storage.object.finalize

The above-mentioned command will deploy the function. This function will get triggered in the event of storage object creation. For further details on cloud function triggers please see the official documentation.

Now, we will copy an image to the bucket to test our recently deployed function. To copy the image, please run the command as mentioned below:

gsutil cp /path/to/images gs://$SOURCE_BUCKET_NAME

The command mentioned above should create a new object in the storage bucket. This event should trigger the cloud function. To verify this, we will run the following command and see the logs:

gcloud functions logs read reformat_image --limit 50

Now, let’s list the output images from destination bucket

gsutil ls gs://$PROCESSED_BUCKET_NAME

Summary

In this blog I used Google Cloud Platform managed services to resize images without deploying any server. To avoid any charges on GCP, make sure to delete the GCS buckets and Cloud Functions.

Hope this blog helps you to understand Cloud Function and it’s usefulness.

Get in touch on LinkedIn or Twitter.

💖 💪 🙅 🚩
dheerajbhadani
dheerajbhadani

Posted on August 2, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related