Images API 示例

区域 ID

REGION_ID 是 Google 根据您在创建应用时选择的区域分配的缩写代码。此代码不对应于国家/地区或省,尽管某些区域 ID 可能类似于常用国家/地区代码和省代码。对于 2020 年 2 月以后创建的应用,REGION_ID.r 包含在 App Engine 网址中。对于在此日期之前创建的现有应用,网址中的区域 ID 是可选的。

详细了解区域 ID

了解如何使用 Images API 动态地上传、转换、存储和传送图片。此示例介绍如何将消息发布到公共留言板,并上传带有问候语的头像。

在数据存储区中创建图片模型

您需要更新留言板示例中的模型,以将上传的图片存储为 blob。

class Greeting(ndb.Model):
    """Models a Guestbook entry with an author, content, avatar, and date."""
    author = ndb.StringProperty()
    content = ndb.TextProperty()
    avatar = ndb.BlobProperty()
    date = ndb.DateTimeProperty(auto_now_add=True)

上传用户图片

您需要修改 HTML 表单以使用户能够上传图片:

  1. 添加一个字段,使用户可以从其计算机中选择要上传的文件。

  2. enctype 属性添加到表单标记,并指定这是一个多部分表单发布。

    self.response.out.write("""
          <form action="/sign?%s"
                enctype="multipart/form-data"
                method="post">
            <div>
              <textarea name="content" rows="3" cols="60"></textarea>
            </div>
            <div><label>Avatar:</label></div>
            <div><input type="file" name="img"/></div>
            <div><input type="submit" value="Sign Guestbook"></div>
          </form>
          <hr>
          <form>Guestbook name: <input value="%s" name="guestbook_name">
          <input type="submit" value="switch"></form>
        </body>
      </html>""" % (urllib.urlencode({'guestbook_name': guestbook_name}),
                    cgi.escape(guestbook_name)))
  3. 更新留言板处理程序,以从表单发布中获取图片数据,然后将其作为 blob 存储在数据存储区中。

    class Guestbook(webapp2.RequestHandler):
        def post(self):
            guestbook_name = self.request.get('guestbook_name')
            greeting = Greeting(parent=guestbook_key(guestbook_name))
    
            if users.get_current_user():
                greeting.author = users.get_current_user().nickname()
    
            greeting.content = self.request.get('content')
    
            avatar = self.request.get('img')
            avatar = images.resize(avatar, 32, 32)
            greeting.avatar = avatar
            greeting.put()
    
            self.redirect('/?' + urllib.urlencode(
                {'guestbook_name': guestbook_name}))

转换图片

要创建 32x32 头像,您需要执行以下操作:

  1. 导入 google.appengine.api.images 模块。

    from google.appengine.api import images
  2. 调用 resize 函数并传入图片数据。

    avatar = images.resize(avatar, 32, 32)

动态地传送图片

要传送图片,您需要执行以下操作:

  1. 创建一个动态传送 /img 路径中图片的图片处理程序。

    class Image(webapp2.RequestHandler):
        def get(self):
            greeting_key = ndb.Key(urlsafe=self.request.get('img_id'))
            greeting = greeting_key.get()
            if greeting.avatar:
                self.response.headers['Content-Type'] = 'image/png'
                self.response.out.write(greeting.avatar)
            else:
                self.response.out.write('No image')
  2. 更新 HTML 以显示这些动态传送的图片。

    self.response.out.write('<div><img src="/img?img_id=%s"></img>' %
                            greeting.key.urlsafe())
    self.response.out.write('<blockquote>%s</blockquote></div>' %
                            cgi.escape(greeting.content))

您需要更新留言板的 HTML,以便在图片处理程序从请求获取 img_id 时将问候语的键传递给图片处理程序。

将应用部署到 App Engine

要上传留言板应用,请从 app.yamlindex.yaml 文件所在的应用的 guestbook 目录中运行以下命令:

gcloud app deploy app.yaml index.yaml

系统可能需要一段时间才能生成数据存储区索引,然后您的应用才可供访问。如果索引仍在生成过程中,您在访问应用时将收到 NeedIndexError 消息。此错误是暂时性的,因此如果您最初收到此错误,请稍后再试。

要详细了解如何从命令行部署应用,请参阅部署 Python 应用

查看已部署的应用

如需启动浏览器并在 https://PROJECT_ID.REGION_ID.r.appspot.com 上查看应用,请运行以下命令:

gcloud app browse