4

I have a Google Cloud Function triggered by Firebase Storage, and I want to generate thumbnails.

While the Node.js docs have an example that uses ImageMagick there is no such equivalent for the python runtime.

What would be an acceptable approach keeping performance in mind ? Would Pillow-SIMD work in a cloud function ?

Or should I go App Engine for thumbnail generation and use the Images service ?

Dustin Ingram
  • 20,502
  • 7
  • 59
  • 82
  • 1
    I am not an expert on Cloud functions, but if you need to generate thumbnails using Imagemagick in Python, then you might want to try Python Wand. My apologies if this suggestion is off topic to what you are asking. – fmw42 Aug 16 '18 at 22:17
  • Yep I might try that, at this point i'm unsure if ImageMagick is available when using Python – Florian d'Erfurth Aug 16 '18 at 22:25
  • 1
    Python Wand needs Imagemagick installed and then makes calls to Imagemagick. See http://docs.wand-py.org/en/0.4.4/ and http://docs.wand-py.org/en/0.4.4/index.html#requirements and http://docs.wand-py.org/en/0.4.4/guide/resizecrop.html#resize-images, though I am not an expert on Wand, either. – fmw42 Aug 16 '18 at 22:50
  • See here for a similar discussion: https://stackoverflow.com/q/8631076/609290 – DazWilkin Aug 16 '18 at 22:54
  • It's unclear whether you're seeking architectural guidance on your approach? Or whether you're seeking "We've done this and...." recommendations from others who've blazed the trail. Generally, if a service already exists and you can use it cost-effectively, why reinvent the wheel? If you can't use existing solutions, build the solution that's closet to your level of comfort. If you ImageMagick and there's a Python SDK for it, use that. – DazWilkin Aug 16 '18 at 22:58

2 Answers2

5

You can use wand, a binding to ImageMagick, along with google-cloud-storage to resize an image automatically once it's uploaded to a storage bucket.

In requirements.txt:

google-cloud-storage
wand

In main.py:

from wand.image import Image
from google.cloud import storage

client = storage.Client()

PREFIX = "thumbnail"


def make_thumbnail(data, context):
    # Don't generate a thumbnail for a thumbnail
    if data['name'].startswith(PREFIX):
        return

    # Get the bucket which the image has been uploaded to
    bucket = client.get_bucket(data['bucket'])

    # Download the image and resize it
    thumbnail = Image(blob=bucket.get_blob(data['name']).download_as_string())
    thumbnail.resize(100, 100)

    # Upload the thumbnail with the filename prefix
    thumbnail_blob = bucket.blob(f"{PREFIX}-{data['name']}")
    thumbnail_blob.upload_from_string(thumbnail.make_blob())

Then you can deploy it with the gcloud tool:

$ gcloud beta functions deploy make_thumbnail \
    --runtime python37 \
    --trigger-bucket gs://[your-bucket-name].appspot.com
Dustin Ingram
  • 20,502
  • 7
  • 59
  • 82
  • dont forget to add `content-type` , something like `thumbnail_blob.upload_from_string(thumbnail.make_blob(), content_type="image/jpeg")` or programatically get the image format and add its correct content type, by default, it uses `text/plain` – Abdelouahab Aug 05 '21 at 04:14
0

I assumed wrongly that ImageMagick wasn't installed in the Google Cloud Function environment when using the Python runtime since it was not documented.

But actually it is, the following cloud function :

import wand.version


def cloud_function(request):
    print(wand.version.MAGICK_VERSION)

outputs ImageMagick 6.9.7-4 Q16 x86_64 20170114 http://www.imagemagick.org