Images API 예시

리전 ID

REGION_ID는 앱을 만들 때 선택한 리전을 기준으로 Google에서 할당하는 축약된 코드입니다. 일부 리전 ID는 일반적으로 사용되는 국가 및 주/도 코드와 비슷하게 표시될 수 있지만 코드는 국가 또는 주/도와 일치하지 않습니다. 2020년 2월 이후에 생성된 앱의 경우 REGION_ID.r이 App Engine URL에 포함됩니다. 이 날짜 이전에 만든 기존 앱의 경우 URL에서 리전 ID는 선택사항입니다.

리전 ID에 대해 자세히 알아보세요.

Images API를 사용하여 이미지를 동적으로 업로드, 변환, 저장, 제공하는 방법을 알아봅니다. 이 예시에서는 공개 게시판에 글을 올리고 아바타와 함께 인사말을 업로드하는 방법을 설명합니다.

Datastore에서 이미지 모델 만들기

업로드된 이미지를 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))

요청에서 img_id를 가져올 때 이미지 핸들러에 인사말 키를 전달하도록 방명록 HTML을 업데이트해야 합니다.

App Engine에 앱 배포

방명록 앱을 업로드하려면 app.yamlindex.yaml 파일이 있는 애플리케이션의 guestbook 디렉터리에서 다음 명령어를 실행합니다.

gcloud app deploy app.yaml index.yaml

애플리케이션이 제공되기 전 Datastore 색인을 생성하는 데 시간이 걸릴 수 있습니다. 색인이 아직 생성 중인 경우에는 앱에 액세스할 때 NeedIndexError 메시지가 표시됩니다. 일시적인 오류이므로 처음에 오류가 발생하면 잠시 후에 다시 시도해주세요.

명령줄에서 앱을 배포하는 방법에 대한 자세한 내용은 Python 앱 배포를 참조하세요.

배포된 애플리케이션 보기

브라우저를 실행하고 https://PROJECT_ID.REGION_ID.r.appspot.com에서 앱을 보려면 다음 명령어를 실행합니다.

gcloud app browse