banner
月落星河Tsukistar

月落星河Tsukistar

浩瀚中的伟大,孤独间的渺小
github
twitter
youtube
bilibili
email

Design and implementation of a system for dynamically resizing images in a serverless environment.

Recently, I chose a graduation project topic related to my previous projects and image processing. Serverless is also a popular service that has emerged in recent years, so I chose this topic to study serverless from scratch. (Postscript: The teacher who assigned the topic later realized that the workload for my project was too small, so they expanded the topic to include document recognition and processing, etc. QwQ)

Reference article: 【AWS Essay】Using AWS Serverless Architecture to Dynamically Adjust Image Size

Development Environment#

Python 3.6 (Tencent Cloud currently only supports this version for Python 3), Tencent Cloud SCF

Steps#

Configure Environment#

In Tencent Cloud's "Serverless Framework", create a new Flask framework with any name and region, as shown below:

Create Framework

After deployment, click "Update Code" in "Development & Deployment":

Update Code

Then choose to download the project locally:

Download Code

(Actually, a more convenient way is to modify the code or add files in "Cloud Function-Function Service-Select the newly created function-Function Code", which ensures consistency of the environment. However, the above method is convenient for local debugging and modification, each with its own advantages and disadvantages)

Cloud Function Online Modification

At this point, the basic framework has been set up.

Function Development#

Currently, the function can process and return images stored in my cloud storage, mainly for ease of calling and reserving parameters. Using the inherent format of the Flask app, two parameters, screen_width (screen width) and pic_url (image path), are reserved. When called, if the screen width is specified, it will return an image with the corresponding width and proportional scaling:

Proportional Scaling

If not specified, it will return the original image:

Original Image

The Flask code is as follows:

@app.route("/pic/<pic_url>")
def source_picture(pic_url):
    img_src = "storage space address" + pic_url
    # Equivalent to reading in and then reading out an image, the image size will become smaller
    response = make_response(picture.image_output(picture.image_input(img_src)))
    # Set the headers object of the response
    response.headers['Content-Type'] = 'image/jpeg'
    return response


@app.route("/pic/<screen_width>/<pic_url>")
def picture_url_get(screen_width, pic_url):
    # Avoid data type errors
    width = int(screen_width)
    img_src = "storage space address" + pic_url
    # Create response object
    response = make_response(picture.image_output(picture.image_resize(width, img_src)))
    # Set the headers object of the response
    response.headers['Content-Type'] = 'image/jpeg'
    return response

make_response is mainly used to create a response object to wrap the image and return it to the browser, avoiding the need to store and then access the stored image.

For the image processing part:

The image_input function uses requests to get the image from the URL, wraps it into a response object, and then opens it with the Image library from PIL. Note that the response object needs to be processed with BytesIO:

def image_input(img_src):
    response = requests.get(img_src, headers=headers)
    image = Image.open(BytesIO(response.content))
    return image

The image_output function uses BytesIO to convert the image into bytes and returns it after saving:

def image_output(image):
    img_byte = BytesIO()
    image.save(img_byte, format="JPEG")
    img_byte = img_byte.getvalue()
    return img_byte

The image_resize function uses the resize method in Image to proportionally scale the image, where Image.ANTIALIAS is a parameter for high definition:

def image_resize(width, img_src):
    image = image_input(img_src)
    resize = image.resize((width, int(image.size[1] * width / image.size[0])), Image.ANTIALIAS)
    return resize

Problems Encountered and Solutions#

npm installation encountered rollbackFailedOptional: verb npm-session problem#

Use the command npm install -g cnpm --registry=https://registry.npm.taobao.org to replace the official source with the Taobao source, and then use cnpm for installation.

Error when installing the corresponding third-party library#

You can use the Aliyun mirror: https://mirrors.aliyun.com/pypi/simple/. At the same time, change the pip-related code in the serverless.yml file to hook: pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt -t ./

Import error for Pillow#

The reason is that the local environment is different from the cloud environment. Even if both are Python 3.6.0, there are slight differences in third-party libraries between Windows and Linux. The solution is to upload the code and execute pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt -t ./ in the cloud environment to download the dependencies.

Summary#

After going through the whole process, I have a general understanding of the steps to deploy a serverless service. I also realized that since the dependencies of serverless are included with the code, if the development and deployment are not on the same operating system, it is recommended to deploy in the cloud environment after uploading the code to avoid runtime errors.

Changing the size of images is just one small application. In theory, many applications can run and produce results in a serverless environment, such as short links, image recognition, text recognition, and so on. The application of serverless will become more and more extensive in the future.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.