0

我正在使用 django non-rel for appengine (djangoappengine) 并且有一个应用程序,用户在其中选择图像,我必须从所选图像返回裁剪。

我的应用程序中的图像按照django-filetransfers 指令上传到 Blobstore 。我已经设法上传(甚至下载)文件就好了。

我遇到的问题是,一旦图像被裁剪,我不知道如何在模板中显示图像。

我的观点的(简化)代码如下:

def canvas_size(request):
if request.method == 'POST':
    #some code here
else:
    #At this point the user has selected an image, and I store its pk in session
    img_file = ImageModel.objects.get(pk=request.session[SESSION_KEY]['image_pk'])
    img = images.Image(blob_key=str(img_file.file.file.blobstore_info.key())) 
    img.resize(height=300)
    img.crop(left_x=0.0, top_y=0.0, right_x=0.5, bottom_y=1.0)
    crop_img = img.execute_transforms(output_encoding=images.JPEG)
    #I know that the image is being cropped because if I do
    #print crop_img
    #I get to see the image in browser
    response_dict = {
        'crop_img' : crop_img,
    }

    template_name = 'canvas/step7.html'
    response = render_to_response(template_name, response_dict, context_instance=RequestContext(request))
    return response

在 canvas/step7.html 我尝试了以下内容:

<img src="{{ crop_img.url }}" />
<img src="{{ crop_img.file.url }}" />

但这当然行不通。

根据Google AppEngine Image documentation,我知道 execute_transforms() 函数将图像的编码表示形式作为字符串返回。所以我想我错过了将字符串转换为文件的步骤......也许?

有人可以指出我正确的方向以便使用 django 在模板中显示裁剪吗?

谢谢你的帮助!

4

2 回答 2

2

我终于设法解决了我的问题。我遵循了 voscausa 的建议,但我发布了一个适用于 Django 的解决方案。

背景: 我不能使用 get_serving_url 因为我需要裁剪特定的坐标。方法execute_transforms返回一个字符串。从 blobstore 可以更好地供应农作物

解决方案

模型.py

from djangotoolbox.fields import BlobField
class ImageModel(models.Model):
    file = models.FileField(upload_to="images")

class MiniCanvas(models.Model):
    crop = BlobField()

视图.py

from my_app.models import ImageModel, MiniCanvas
from google.appengine.api import images

def view_that_crops(request):
 if request.method == 'POST':
        #Do stuff here
    else:
        #The pk of the selected image is stored in session
        img_file = ImageModel.objects.get(pk=request.session[SESSION_KEY]['image_pk'])
        img = images.Image(blob_key=str(img_file.file.file.blobstore_info.key())) 
        img.resize(height=300)
        img.crop(left_x=0.0, top_y=0.0, right_x=0.5, bottom_y=1.0)

        #This method returns the image's encoded representation as a string
        crop_img = img.execute_transforms(output_encoding=images.JPEG)
        #I can save the string as a BlobField in my model
        mini_canvas = MiniCanvas.objects.create(crop=crop_img)
        response_dict = {
            'mini_canvas_pk' : mini_canvas.pk,
        }

        template_name = 'canvas/step7.html'
        response = render_to_response(template_name, response_dict, context_instance=RequestContext(request))
        return response

#This function will be called in template
def show_crop(request, crop_pk):
    try:
        crop = MiniCanvas.objects.get(pk=crop_pk)
    except MiniCanvas.DoesNotExist:
        crop = None
    if not crop:
        #TODO: return a default image maybe?
        return HttpResponse()
    #Don't forget content_type
    return HttpResponse(crop.crop, content_type="image/jpeg")

网址.py

from my_app.views import show_crop, view_that_crops
urlpatterns = patterns('',
    url(r'^cropper/(?P<crop_pk>\d+)/$', show_crop, name='show_crop'),
)

模板“画布/step7.html”

<img src="{% url show_crop mini_canvas_pk %}" alt="The crop you were looking for" />

就是这样。我不明白的是如何在模板中调用 voscausa 建议的处理程序。(我是新来的:()

这是一个关于如何裁剪图像并将其显示在模板中的完整示例。但是,我相信可以(并且应该)进行一些改进。如:裁剪作为后台任务避免性能问题;或使用memecache ...

我希望这对其他人有帮助!

编辑 我可能应该补充一点,models.py 中的 BlobField 起初并不明显。由于这个 google group 的讨论,我发现了它。

于 2013-06-04T15:49:53.983 回答
0

您必须将裁剪的图像保存在上述代码中的数据存储或 blobstore 中,并且可以使用缓存 (memcache)。

现在您可以编写一个处理程序来提供图像 url。

Blobstore 处理程序示例:

class ImgServe(blobstore_handlers.BlobstoreDownloadHandler):

    def get(self, resource):    # resource contains the blob_key + image type (like .jpeg)                                   

        (key, _, _) = resource.rpartition('.')
        blob_info = blobstore.BlobInfo.get(key)
        self.response.headers[str('Content-Type')] = str(blob_info.content_type)     
        self.send_blob(blob_info, save_as=True)

作为替代方案,您还可以使用 get_serving_url 进行动态裁剪。在这种情况下,您不必自己裁剪图像,而是使用 Google 高性能图像服务和 get_serving_url 来获取它。在这种情况下,您不必编写处理程序。

另请参阅此答案:Python Google App Engine Image object

于 2013-06-01T20:37:02.080 回答