Наглядный пример использования Google App Engine Images get_serving_url () - PullRequest
1 голос
/ 04 июля 2011

Кто-нибудь знает пример этого? Я не смог найти его в документации Google.

Ответы [ 4 ]

7 голосов
/ 08 августа 2014

Несмотря на документацию, Я тоже немного растерялся .

Теперь, когда я понимаю это лучше (я думаю!), Я приведу пример.

get_serving_url() находится в классе google.appengine.ext.blobstore, а принимает один позиционный аргумент , BlobKey.

A BlobKey может быть построен из строки: blobstore.BlobKey('this is the key').

Итак, это дает нам все необходимое для базовой реализации get_serving_url():

from google.appengine.ext.blobstore import BlobKey
from google.appengine.api.images import get_serving_url

key = BlobKey('imagekey')
url = get_serving_url(key)

Пока все отлично и прекрасно.

Функция такжепринимает три ключевых аргумента, как задокументировано .Это size, crop, secure_url и rpc.

  • secure_url = True просто возвращает https url вместо http (по умолчанию False)
  • rpc - это объект RPC с некоторыми настройками для асинхронной обработки.Я не понимаю этого достаточно, чтобы объяснить или даже использовать это сам!
  • crop = True обрезает квадрат изображения четными пропорциями.

size - вот что смутилоя сначала. не не генерирует разные URL как таковые.Единственное отличие заключается в суффиксе =sXX, который вы можете установить самостоятельно.

Лично я сохраняю URL оригинального размера в моем db.Model, а затем выполняю imgUrl+'=s150' (например) везде, где это возможно.используемый.Нет необходимости вызывать get_serving_url() для каждого нужного вам размера, никакого снижения производительности, потому что он делает то же самое.

Обратите также внимание, что указанный размер является наибольшим размером изображения.Любопытно, что это скрыто в документах - я предположил, что на какое-то время это должна быть ширина, но если изображение «портретное», конечно, это высота.

Вы также можете добавить -c (эквивалентноcrop=True).

Итак, для нашего более полного (хотя мне не хватает знаний, чтобы продемонстрировать использование RPC объекта), пример:

from google.appengine.ext.blobstore import BlobKey
from google.appengine.api.images import get_serving_url
from webapp2 import RequestHandler

class sample(RequestHandler):

    def get(self):
        key = BlobKey('imagekey')
        url = get_serving_url(key, secure_url=True)

        #get_serving_url(key, secure_url=True, size=150, crop=True)
        urlThumb = url + '=s150-c'

        #get_serving_url(key, secure_url=True, size=50)
        urlMini  = url + '=s50'

        self.response.write('Here is my thumbnail: <img src="%s"><br>'%urlThumb)
        self.response.write('Here is mini-me!: <img src="%s"><br>'%urlMini)
        self.response.write('And back to full-size: <img src="%s"><br>'%url)

Эти URL могут быть сохраненыв хранилище данных в любой модели, к которой они имеют отношение.Это предпочтительнее, чем использование совершенно другого db.BlobProperty, что совсем не для изображений.Это также более дорого и менее эффективно.

Конечно, я бы посоветовал вам хранить только url (как указано выше), потому что изменить размер очень просто, добавив суффикс строки!На самом деле, это то, что вы можете просто сделать в своем шаблоне Jinja (или эквивалентном), где вы, вероятно, в противном случае задали бы width= и обрезали бы, делая то же самое в CSS.

4 голосов
/ 04 июля 2011

get_serving_url задокументировано здесь . Там нет сквозного примера как такового, но он довольно прост: вы передаете ему ключ BLOB-объекта вместе с необязательными параметрами изменения размера и обрезки, и он возвращает вам URL. Вы можете использовать этот URL в любом месте, где хотите сослаться на изображение, и оно будет обслуживаться инфраструктурой, изменяться в размерах и обрезаться соответствующим образом.

Обратите внимание, что это только для изображений, загруженных в blobstore. Все, что загружено в обычное хранилище данных и хранится в BlobProperty, вам придется изменять, обрезать и обслуживать самостоятельно.

2 голосов
/ 18 января 2017

Я использовал следующий код для загрузки изображений и их последующего использования с использованием CDN. Пожалуйста, обратитесь к комментариям в коде для объяснения.

import webapp2
from google.appengine.api import users
import os
import jinja2
from models import Note
from models import NoteFile
from models import CheckListItem
from google.appengine.ext import ndb
from google.appengine.api import app_identity
from google.appengine.api import images
from google.appengine.ext import blobstore
import lib.cloudstorage as cloudstorage
import mimetypes

jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))

#Request Handler
class MainHandler(webapp2.RequestHandler):  
    #Post Method for uploading images  
    def post(self):
        #Gets the currently logged in user
        user = users.get_current_user() 
        if user is None:
            self.error(401)
        #Gets Default Bucket for Google Cloud Storage. This is where uploaded image will be saved
        bucket_name = app_identity.get_default_gcs_bucket_name()
        uploaded_file = self.request.POST.get('uploaded_file')
        file_name = getattr(uploaded_file, 'filename', None)
        file_content = getattr(uploaded_file, 'file', None)
        real_path = ''

        if file_name and file_content:
            content_t = mimetypes.guess_type(file_name)[0]
            real_path = os.path.join('/', bucket_name, user.user_id(), file_name)
            #Read file from the uploaded stream and write to the cloud storage bucket
            with cloudstorage.open(real_path, 'w', content_type=content_t) as f:
                f.write(file_content.read())
        else:
            print 'File can not be written'
        #This will save the NDB models
        self._create_note(user, file_name, real_path)

        logout_url = users.create_logout_url(self.request.uri)
        template_context = {
            'user': user.nickname(),
            'logout_url': logout_url
        }
        #Response with the data
        self.response.write(self._render_template('main.html', template_context))

    #Makes the method atomic
    @ndb.transactional
    def _create_note(self, user, file_name, file_path):
        note = Note(parent=ndb.Key("User", user.nickname()),
                    title=self.request.get('title'),
                    content=self.request.get('content'))
        note.put()

        if file_name and file_path:
            url, thumbnail_url = self._get_urls_for(file_name)
            f = NoteFile(parent=note.key, name=file_name, url=url, thumbnail_url=thumbnail_url, full_path=file_path)
            f.put()
            note.files.append(f.key)
        note.put()

    def _render_template(self, template_name, context=None):
        if context is None:
            context = {}
        user = users.get_current_user()
        ancestor_key = ndb.Key("User", user.nickname())
        qry = Note.owner_query(ancestor_key)
        context['notes'] = qry.fetch()
        template = jinja_env.get_template(template_name)
        return template.render(context)

    def _get_urls_for(self, file_name):
        user = users.get_current_user()
        if user is None:
            return
        #Gets Default Bucket
        bucket_name = app_identity.get_default_gcs_bucket_name()
        path = os.path.join('/', bucket_name, user.user_id(), file_name)
        #This is required to generate the blobstore key
        real_path = '/gs' + path
        key = blobstore.create_gs_key(real_path)
        #This is going to generate url for original sized image
        url = images.get_serving_url(key, size=0)
        #Generates url for cropped and 150px max dimension image. The image will be uploaded once, but will dynamically be transformed acc to parameters provided
        thumbnail_url = images.get_serving_url(key, size=150, crop=True)
        return url, thumbnail_url


app = webapp2.WSGIApplication([
    (r'/', MainHandler)
], debug=True)

Вот модель классов

class Note(ndb.Model):
    title = ndb.StringProperty()
    content = ndb.TextProperty()
    date_created = ndb.DateTimeProperty(auto_now_add=True)
    files = ndb.KeyProperty("NoteFile",repeated=True)

    @classmethod
    def owner_query(cls, parent_key):
        return cls.query(ancestor=parent_key).order(-cls.date_created)


class NoteFile(ndb.Model):
    name = ndb.StringProperty()
    url = ndb.StringProperty()
    thumbnail_url = ndb.StringProperty()
    full_path = ndb.StringProperty()

Дайте мне знать, если здесь что-то непонятно.

0 голосов
/ 05 октября 2014

Я также был сильно смущен, так как Google на самом деле не предоставляет рабочий пример getServingUrl () для программистов JAVA - Олли, я думаю, что приведенный выше пример кода написан на Python?

Я сделал несколько кодов, чтобы посмотреть, как это работает, и вот фрагмент рабочего кода в java (можно легко взять рабочий пример с сайта Google: https://cloud.google.com/appengine/docs/java/blobstore/ и заменить код, написанный в Serve.java, на этот кусок кода):

   @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res)
        throws IOException {
            BlobKey blobKey = new BlobKey(req.getParameter("blob-key"));

            ImagesService imagesService = ImagesServiceFactory.getImagesService();

            String url = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKey).crop(true).imageSize(200));
            PrintWriter out = res.getWriter();
            out.println("Here is my thumbnail! <img src="+ url + ">");

        }
}

Это приведет к тому, что изображение, которое вы разместили в своем интернет-магазине, обрежет его так, чтобы оно стало красивым квадратом с шириной и высотой 200, а затем распечатает его в HTML, чтобы вы могли видеть эскиз.

Надеюсь, это кому-нибудь поможет!

...