Вопрос:

Наглядный пример использования Google App Engine Images get_serving_url ()

google-app-engine image-processing google-cloud-platform blobstore

4930 просмотра

4 ответа

908 Репутация автора

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

Автор: a.m. Источник Размещён: 04.07.2011 12:26

Ответы (4)


3 плюса

94774 Репутация автора

Решение

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

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

Автор: Nick Johnson Размещён: 04.07.2011 03:17

7 плюса

4560 Репутация автора

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

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

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

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просто возвращает httpsURL вместо 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.

Автор: OJFord Размещён: 07.08.2014 11:48

0 плюса

11063 Репутация автора

Я также был очень смущен, так как 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, чтобы вы могли видеть миниатюру.

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

Автор: Simon Размещён: 05.10.2014 04:55

1 плюс

11677 Репутация автора

Я использовал следующий код для загрузки изображений, а затем обслуживать их с помощью 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()

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

Автор: noob Размещён: 18.01.2017 06:12
Вопросы из категории :
32x32