1

有人知道这方面的例子吗?我无法在 Google 的文档中找到一个。

4

4 回答 4

7

尽管有文档,但我也有一段时间很困惑。

现在我更好地理解了它(我认为!),我将提供一个例子。

get_serving_url()google.appengine.ext.blobstore课堂上,并接受一个位置参数,即BlobKey.

ABlobKey可以从字符串构造: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)

到目前为止一切都很好。

该函数还采用三个关键字参数,如文档所述。它们是sizecropsecure_urlrpc

  • secure_url = True只返回一个httpsurl 而不是http(默认,False
  • rpcRPC异步处理的一些设置的对象。我理解的不够多,无法解释,甚至无法自己使用!
  • crop = True按均匀比例裁剪图像正方形。

size起初让我感到困惑。它本身不会生成不同的 URL。唯一的区别在于后缀=sXX,您可以自行设置。

就个人而言,我将原始大小的 URL 存储在 mydb.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 中指定和裁剪。

于 2014-08-07T23:48:45.093 回答
4

get_serving_url记录在这里。本身没有端到端的示例,但它非常简单:您向它传递一个 blob 键,以及可选的调整大小和裁剪选项,它会返回一个 URL。您可以在任何想要引用图像的地方使用该 URL,它会由基础设施提供,并适当调整大小和裁剪。

请注意,这仅适用于上传到 blobstore 的图像。任何上传到常规数据存储并存储在BlobProperty您必须自己调整大小、裁剪和服务的内容。

于 2011-07-04T03:17:13.747 回答
2

我一直在使用以下代码上传图像,然后使用 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()

如果这里有什么不清楚的地方,请告诉我。

于 2017-01-18T06:12:04.670 回答
0

我也很困惑,因为谷歌并没有真正为 JAVA 程序员提供 getServingUrl() 的工作示例——Ollie,我认为你上面给出的示例代码是用 Python 编写的?

我做了一些编码来看看它是如何工作的,这是一个 java 中的工作代码片段(人们可以很容易地从谷歌的网站上获取工作示例: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 + ">");

        }
}

这会将您发布到 blobstore 的图像进行裁剪,使其成为一个宽高为 200 的漂亮正方形,然后以 HTML 格式打印出来,以便您可以看到缩略图。

希望这可以帮助那里的人!

于 2014-10-05T16:55:36.163 回答