0

私はappengine(djangoappengine)にdjango non-relを使用しており、ユーザーが画像を選択するアプリがあり、選択した画像から切り抜きを返す必要があります。

私のアプリの画像は、 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を使用してテンプレートにクロップを表示するために、誰かが私を正しい方向に向けることができますか?

ご協力いただきありがとうございます!

4

2 に答える 2

2

私はついに私の問題を解決することができました。私は voscausa のアドバイスに従いましたが、Django に適応したソリューションを投稿しています。

背景: 特定の座標をトリミングする必要があるため、get_serving_url を使用できませんでした。メソッドexecute_transformsは文字列を返します。作物はブロブストアからより適切に提供されます

解決

models.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")

urls.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'),
)

テンプレート 'canvas/step7.html'

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

で、これです。私が理解できなかったのは、テンプレートで voscausa によって提案されたハンドラーを呼び出す方法でした。(私はこれが初めてです:()

これは、画像をトリミングしてテンプレートに表示する方法の完全な例です。ただし、いくつかの改善を行うことができます (また、行う必要があります)。例: パフォーマンスの問題を回避するためのバックグラウンド タスクとしてのクロッピング。またはmemecacheを使用して...

これが他の誰かに役立つことを願っています!

編集 models.py の BlobField は最初は明らかではないことをおそらく追加する必要があります。このGoogleグループでの議論のおかげで、私はそれについて知りました。

于 2013-06-04T15:49:53.983 に答える
0

トリミングした画像を上記のコードでデータストアまたはブロブストアに保存する必要があり、キャッシュ (memcache) を使用できます。

これで、画像の URL を提供するハンドラーを作成できます。

ブロブストア ハンドラーの例:

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 High Performance Image Serving と get_serving_url を使用して取得します。この場合、ハンドラを記述する必要はありません。

この回答も参照してください: Python Google App Engine Image object

于 2013-06-01T20:37:02.080 に答える