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.
Top comments (0)