我正在使用django non-rel作为appengine(djangoappengine)并且有一个用户选择图像的应用程序,我必须从所选图像返回裁剪。
我的应用中的图片会在django-filetransfers instructions之后上传到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在模板中显示裁剪吗?
感谢您的帮助!
答案 0 :(得分:2)
我终于设法解决了我的问题。我遵循了voscausa的建议,但我发布了一个适合Django的解决方案。
<强>背景强> 我无法使用get_serving_url,因为我需要裁剪特定的坐标。 方法 execute_transforms 返回一个字符串。 从blobstore
可以更好地提供作物<强>解决方案强>
from djangotoolbox.fields import BlobField
class ImageModel(models.Model):
file = models.FileField(upload_to="images")
class MiniCanvas(models.Model):
crop = BlobField()
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")
from my_app.views import show_crop, view_that_crops
urlpatterns = patterns('',
url(r'^cropper/(?P<crop_pk>\d+)/$', show_crop, name='show_crop'),
)
<img src="{% url show_crop mini_canvas_pk %}" alt="The crop you were looking for" />
就是这样。我不明白的是如何在模板中调用voscausa建议的处理程序。 (我是新来的:()
这是关于如何裁剪图像并在模板中显示图像的完整示例。但是,我相信可以(而且应该)做出一些改进。如:裁剪作为后台任务,以避免性能问题;或使用memecache ......
我希望这有助于其他人!
编辑我应该补充一点,models.py中的BlobField最初并不明显。由于discussion in this google group,我找到了它。
答案 1 :(得分:0)
您必须将裁剪后的图像保存在上述代码的数据存储区或blobstore中,然后才能使用缓存(memcache)。
现在你可以写一个处理程序来提供图片网址。
Blobstore Handler示例:
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来获取图像。在这种情况下,您不必编写处理程序。