应该在内存(.py)还是视图(HTML)中合并图像? [英] Should I merge images in memory (.py) or in view (HTML)?

查看:134
本文介绍了应该在内存(.py)还是视图(HTML)中合并图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Facebook应用程序可让用户上传图像,选择图像(眼睛,鼻子,嘴或其他身体部位),然后可以通过按类别选择三个随机图像组合,并且工作正常,并且代码看起来确定和可读性,但不是很高级:

 $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $))))))))))))))))))))))))))))))))))))))))))))))))))))))) 
return fileinfos [random.randint(0,fileinfos.count() - 1)]

def get(self):
eyes_image = self.get_random_image(category =eyes )
nose_image = self.get_random_image(category =nose)
mouth_image = self.get_random_image(category =mouth)
eyes_data =无
try:
eyes_data = blobstore.fetch_data(eyes_image.blob.key(),0,50000)
除了异常,e:
self.set_messag e(type = u'error',
content = u'无法找到文件'+ str(eyes_image.key()。id())+'('+ unicode(e)+ u' )')

eyes_img =无

try:
eyes_img = images.Image(image_data = eyes_data)
/ pre>

...现在我只是获取3个随机图像,然后在模板中组合:

 < a href =/ file / {{eyes_image.key.id}}>< img src ={{eyes_url}}>< / a>峰; br> 
< a href =/ file / {{nose_image.key.id}}>< img src ={{nose_url}}>< / a>< br&
< a href =/ file / {{mouth_image.key.id}}>< img src ={{mouth_url}}>< / a>

可以通过发送将三个图像组合成一个的合成图像来改进吗?有利的是,图像上的所有内容都将同时加载,并且如果随机化下一次结果已被保存,它将被保存。你觉得怎么样?



谢谢(应用程序是apps.facebook.com/cyberfaze你可以检查我做的乐趣和学习)



整个课程是

  class Cyber​​FazeHandler(BaseHandler):

def get_random_image(self,category):
fileinfos = FileInfo.all()。filter(category =,category)
return fileinfos [random.randint(0,fileinfos.count() ] #optimize

def get(self):
eyes_image = self.get_random_image(category =eyes)
nose_image = self.get_random_image(category =nose)
mouth_image = self.get_random_image(category =mouth)
eyes_data =无
try:
eyes_data = blobstore.fetch_data(eyes_image.blob.key(),0,50000)
除了异常,e:
self.set_message(type = u'error',
content = u'无法找到文件'+ str(eyes_image.key()。id ())+'('+ unicode(e)+ u')'

eyes_img =无

try:
eyes_img = images.Image(image_data = eyes_data)
除了异常,e:
self.set_message(type = u'error',
content = u'Could not find eyes img for file'+ str(eyes_image.key()。id())+'('+ unicode e)+ u')')


nose_data =无
try:
nose_data = blobstore.fetch_data(nose_image.blob.key(),0,50000 )
除了异常,e:
self.set_message(type = u'error',
content = u'找不到文件'+ str(nose_image.key()的鼻子数据。 id())+'('+ unicode(e)+ u')')


nose_img =无

try:
nose_img = image.Image(image_data = nose_data)
除了异常,e:
self.set_message(type = u'error',
content = u'Could not find nose img for file'+ str (鼻子图像)()+'('+ unicode(e)+ u')')


mouth_data =无
try:
mouth_data = blobstore.fetch_data(mouth_image.blob.key(),0,50000)
除了异常,e:
self.set_message(type = u'error',
content = u '找不到文件'+ str(eyes_image.key()。id())+'('+ unicode(e)+ u')'的口数据


mouth_img =无

try:
mouth_img = images.Image(image_data = mouth_data)
除了异常,e:
self.set_message(type = u'error'
content = u'无法找到文件'+ str(mouth_image.key()。id())+'('+ unicode(e)+ u')''


minimum = min(int(eyes_img.width),int(nose_img.width),int(mouth_img.width))

eyes_url = images.get_serving_url(str(eyes_image.blob .key()),size = minimum)
nose_url = images.get_serving_ url(str(nose_image.blob.key()),size = minimum)
mouth_url = images.get_serving_url(str(mouth_image.blob.key()),size = minimum)

self.render(u'cyberfaze',minimum = minimum,eyes_image = eyes_image,eyes_url = eyes_url,nose_image = nose_image,nose_url = nose_url,mouth_image = mouth_image,mouth_url = mouth_url,form_url = blobstore.create_upload_url('/ upload'))

重写后,它的工作原理如下:

  class Cyber​​FazeHandler(BaseHandler):

def get_random_image(self,category):

q = FileInfo.all()
q.filter('category =',category)
q.filter('randomvalue> =',random.random())
返回q.get()

def get_random_image_legacy(self,category):
fileinfos = FileInfo.all()。filter('category =',category)
return fileinfos [random.randint(0,fileinfos.count() ]

def get(self):

eyes_image = self.get_random_image(category ='eyes')
如果不是eyes_image:
logging.debug(让眼睛失败,尝试传统方法)
eyes_image = self.get_random_image_legacy (category ='eyes')
nose_image = self.get_random_image(category ='nose')
如果不是nose_image:
nose_image = self.get_random_image_legacy(category ='nose')

mouth_image = self.get_random_image(category ='mouth')
如果不是mouth_image:
mouth_image = self.get_random_image_legacy(category ='mouth')

eyes_data =无
try:
eyes_data = blobstore.fetch_data(eyes_image.blob.key(),0,
50000)
除了异常,e:
self.set_message (type = u'error',
content = u'找不到文件'
+ str(eyes_image.key())的眼睛数据。 id())+'('
+ unicode(e)+ u')')

eyes_img =无

try:
eyes_img = image.Image(image_data = eyes_data)
除了异常,e:
self.set_message(type = u'error',
content = u'Could not find eyes img for file'
+ str(eyes_image.key()。id())+'('
+ unicode(e)+ u')')

nose_data =无
try :
nose_data = blobstore.fetch_data(nose_image.blob.key(),0,
50000)
除了异常,e:
self.set_message(type = u'error' ,
content = u'找不到文件'
+ str(nose_image.key()。id())+'('
+ unicode(e)+ u' )')

nose_img = N一个

try:
nose_img = images.Image(image_data = nose_data)
除了异常,e:
self.set_message(type = u'error',
content = u'找不到文件'
+ str(nose_image.key()。id())+'('
+ unicode(e)+ u')的文件' )

mouth_data =无
try:
mouth_data = blobstore.fetch_data(mouth_image.blob.key(),
0,50000)
除异常,e:
self.set_message(type = u'error',
content = u'找不到文件'
+ str(eyes_image.key()。id() )+'('
+ unicode(e)+ u')')

mouth_img =无

try:
mouth_img = images.Image (image_data = mouth_data)
除了异常,e:
self.set_message(type = u'error',
content = u'无法找到文件'
+ str(mouth_image.key()。id ())+'('
+ unicode(e)+ u')')

minimum = min(int(eyes_img.width),int(nose_img.width),
int(mouth_img.width))

eyes_url = images.get_serving_url(str(eyes_image.blob.key()),
size = minimum)
nose_url = images。 get_serving_url(str(nose_image.blob.key()),
size = minimum)
mouth_url = images.get_serving_url(str(mouth_image.blob.key()),
size = minimum)

self.render(
u'cyberfaze',
minimum = minimum,
eyes_image = eyes_image,
eyes_url = eyes_url,
nose_image = nose_image,
nose_ur l = nose_url,
mouth_image = mouth_image,
mouth_url = mouth_url,
form_url = blobstore.create_upload_url('/ upload'),


解决方案

哪个更有效率取决于如何使用它。如果用户将加载大量的这些混搭,那么将其作为单独的图像发送更有意义,因为浏览器缓存的图像(a + b + c图像而不是* b * c)将会更少。



然而,您的代码有一个更令人震惊的性能问题:

  get get_random_image(self,category):
fileinfos = FileInfo.all()。filter(category =,category)
return fileinfos [random.randint(0,fileinfos.count() )]

每次调用此函数时,它将执行一个计数操作,它是O(n ),其数量为 FileInfo 实体,然后执行偏移查询,这是偏移量为O(n)。这是非常缓慢和低效的,并且会增加更多的图像数量。



如果您希望图像集小(少于几个一千个),并且相当不变,只需将其存储在代码中,这将比任何其他选项快。如果集合较大或在运行时更改,则为每个实体分配0到1之间的随机值,并使用这样的查询来检索随机选择的一个:

  q = FileInfo.all()
q.filter('category =',category)
q.filter('random> =',random.random ())
return q.get()


My facebook app lets the user upload an image, select what the image is (eyes, nose, mouth or other body part) and then can combine by selecting three random images by category and that's works fine and the code looks ok and readable though not very advanced:

class CyberFazeHandler(BaseHandler):

    def get_random_image(self, category):
        fileinfos = FileInfo.all().filter("category =", category)
        return fileinfos[random.randint(0, fileinfos.count()-1)] 

    def get(self):
        eyes_image = self.get_random_image(category="eyes")
    nose_image = self.get_random_image(category="nose")
    mouth_image = self.get_random_image(category="mouth")
        eyes_data = None
        try:
        eyes_data = blobstore.fetch_data(eyes_image.blob.key(), 0, 50000)
        except Exception, e:
            self.set_message(type=u'error',
                content=u'Could not find eyes data for file '+str(eyes_image.key().id())+' (' + unicode(e) + u')')

        eyes_img = None

        try:
            eyes_img = images.Image(image_data=eyes_data)

...now I just fetch 3 random images and then combine then in the template:

<a href="/file/{{eyes_image.key.id}}"><img src="{{eyes_url}}"></a><br>
<a href="/file/{{nose_image.key.id}}"><img src="{{nose_url}}"></a><br>
<a href="/file/{{mouth_image.key.id}}"><img src="{{mouth_url}}"></a>

Could this be improved by sending a composite image combining the three images into one? With the advantage that everything on the image will load at the same time and that it will be saved already if a randomization comes up next time the result is already saved. What do you think?

Thank you (the application is apps.facebook.com/cyberfaze you may inspect I did for fun and learning)

The entire class is

class CyberFazeHandler(BaseHandler):

    def get_random_image(self, category):
        fileinfos = FileInfo.all().filter("category =", category)
        return fileinfos[random.randint(0, fileinfos.count()-1)] #optimize

    def get(self):
        eyes_image = self.get_random_image(category="eyes")
    nose_image = self.get_random_image(category="nose")
    mouth_image = self.get_random_image(category="mouth")
        eyes_data = None
        try:
        eyes_data = blobstore.fetch_data(eyes_image.blob.key(), 0, 50000)
        except Exception, e:
            self.set_message(type=u'error',
                content=u'Could not find eyes data for file '+str(eyes_image.key().id())+' (' + unicode(e) + u')')

        eyes_img = None

        try:
            eyes_img = images.Image(image_data=eyes_data)
        except Exception, e:
            self.set_message(type=u'error',
                content=u'Could not find eyes img for file '+str(eyes_image.key().id())+' (' + unicode(e) + u')')


        nose_data = None
        try:
            nose_data = blobstore.fetch_data(nose_image.blob.key(), 0, 50000)
        except Exception, e:
            self.set_message(type=u'error',
                content=u'Could not find nose data for file '+str(nose_image.key().id())+' (' + unicode(e) + u')')


        nose_img = None

        try:
            nose_img = images.Image(image_data=nose_data)
        except Exception, e:
            self.set_message(type=u'error',
                content=u'Could not find nose img for file '+str(nose_image.key().id())+' (' + unicode(e) + u')')


        mouth_data = None
        try:
        mouth_data = blobstore.fetch_data(mouth_image.blob.key(), 0, 50000)
        except Exception, e:
            self.set_message(type=u'error',
                content=u'Could not find mouth data for file '+str(eyes_image.key().id())+' (' + unicode(e) + u')')


        mouth_img = None

        try:
            mouth_img = images.Image(image_data=mouth_data)
        except Exception, e:
            self.set_message(type=u'error',
                content=u'Could not find mouth img for file '+str(mouth_image.key().id())+' (' + unicode(e) + u')')


    minimum = min(int(eyes_img.width), int(nose_img.width), int(mouth_img.width))

    eyes_url = images.get_serving_url(str(eyes_image.blob.key()), size=minimum)
    nose_url = images.get_serving_url(str(nose_image.blob.key()), size=minimum)
    mouth_url = images.get_serving_url(str(mouth_image.blob.key()), size=minimum)

        self.render(u'cyberfaze', minimum=minimum, eyes_image=eyes_image, eyes_url=eyes_url, nose_image=nose_image, nose_url=nose_url, mouth_image=mouth_image, mouth_url=mouth_url, form_url = blobstore.create_upload_url('/upload'),)

After rewrite it's working like said:

class CyberFazeHandler(BaseHandler):

    def get_random_image(self, category):

        q = FileInfo.all()
        q.filter('category =', category)
        q.filter('randomvalue >=', random.random())
        return q.get()

    def get_random_image_legacy(self, category):
        fileinfos = FileInfo.all().filter('category =', category)
        return fileinfos[random.randint(0, fileinfos.count() - 1)]

    def get(self):

        eyes_image = self.get_random_image(category='eyes')
    if not eyes_image:
       logging.debug("getting eyes failed, trying legacy method")
           eyes_image = self.get_random_image_legacy(category='eyes')
        nose_image = self.get_random_image(category='nose')
    if not nose_image:
           nose_image = self.get_random_image_legacy(category='nose')

        mouth_image = self.get_random_image(category='mouth')
    if not mouth_image:
           mouth_image = self.get_random_image_legacy(category='mouth')

        eyes_data = None
        try:
            eyes_data = blobstore.fetch_data(eyes_image.blob.key(), 0,
                    50000)
        except Exception, e:
            self.set_message(type=u'error',
                             content=u'Could not find eyes data for file '
                              + str(eyes_image.key().id()) + ' ('
                             + unicode(e) + u')')

        eyes_img = None

        try:
            eyes_img = images.Image(image_data=eyes_data)
        except Exception, e:
            self.set_message(type=u'error',
                             content=u'Could not find eyes img for file '
                              + str(eyes_image.key().id()) + ' ('
                             + unicode(e) + u')')

        nose_data = None
        try:
            nose_data = blobstore.fetch_data(nose_image.blob.key(), 0,
                    50000)
        except Exception, e:
            self.set_message(type=u'error',
                             content=u'Could not find nose data for file '
                              + str(nose_image.key().id()) + ' ('
                             + unicode(e) + u')')

        nose_img = None

        try:
            nose_img = images.Image(image_data=nose_data)
        except Exception, e:
            self.set_message(type=u'error',
                             content=u'Could not find nose img for file '
                              + str(nose_image.key().id()) + ' ('
                             + unicode(e) + u')')

        mouth_data = None
        try:
            mouth_data = blobstore.fetch_data(mouth_image.blob.key(),
                    0, 50000)
        except Exception, e:
            self.set_message(type=u'error',
                             content=u'Could not find mouth data for file '
                              + str(eyes_image.key().id()) + ' ('
                             + unicode(e) + u')')

        mouth_img = None

        try:
            mouth_img = images.Image(image_data=mouth_data)
        except Exception, e:
            self.set_message(type=u'error',
                             content=u'Could not find mouth img for file '
                              + str(mouth_image.key().id()) + ' ('
                             + unicode(e) + u')')

        minimum = min(int(eyes_img.width), int(nose_img.width),
                      int(mouth_img.width))

        eyes_url = images.get_serving_url(str(eyes_image.blob.key()),
                size=minimum)
        nose_url = images.get_serving_url(str(nose_image.blob.key()),
                size=minimum)
        mouth_url = images.get_serving_url(str(mouth_image.blob.key()),
                size=minimum)

        self.render(
            u'cyberfaze',
            minimum=minimum,
            eyes_image=eyes_image,
            eyes_url=eyes_url,
            nose_image=nose_image,
            nose_url=nose_url,
            mouth_image=mouth_image,
            mouth_url=mouth_url,
            form_url=blobstore.create_upload_url('/upload'),
            )

解决方案

Which is more efficient depends on how it'll be used. If the user will be loading a lot of these mashups, it makes more sense to send them as separate images, because there will be fewer images for the browser to cache (a+b+c images instead of a*b*c).

Your code has a much more egregious performance issue, however:

def get_random_image(self, category):
    fileinfos = FileInfo.all().filter("category =", category)
    return fileinfos[random.randint(0, fileinfos.count()-1)] 

Every time you call this function, it will perform a count operation, which is O(n) with the number of FileInfo entities, then perform an offset query, which is O(n) with the offset. This is extremely slow and inefficient, and will get more so as you increase the number of images.

If you expect the set of images to be small (less than a few thousand) and fairly constant, simply store them in code, which will be faster than any other option. If the set is larger, or changes at runtime, assign a random value between 0 and 1 to each entity, and use a query like this to retrieve a randomly selected one:

q = FileInfo.all()
q.filter('category =', category)
q.filter('random >=', random.random())
return q.get()

这篇关于应该在内存(.py)还是视图(HTML)中合并图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆