4

Apache2 + PIL + Django+X-sendfileがあります。私の問題は、アニメーションGIFを保存するときに、ブラウザから出力したときに「アニメーション化」されないことです。

これは、パブリックアクセス可能なディレクトリの外にある画像を表示するための私のコードです。

def raw(request,uuid):
    target = str(uuid).split('.')[:-1][0]
    image = Uploads.objects.get(uuid=target)

    path = image.path
    filepath = os.path.join(path,"%s.%s" % (image.uuid,image.ext))

    response = HttpResponse(mimetype=mimetypes.guess_type(filepath)) 
    response['Content-Disposition']='filename="%s"'\
                                    %smart_str(image.filename)
    response["X-Sendfile"] = filepath
    response['Content-length'] = os.stat(filepath).st_size

    return response

アップデート

それが機能することがわかります。私の問題は、URLを介して画像をアップロードしようとしたときです。おそらくGIF全体を保存しませんか?

def handle_url_file(request):
    """
    Open a file from a URL.
    Split the file to get the filename and extension.
    Generate a random uuid using rand1()
    Then save the file.
    Return the UUID when successful.
    """

    try:
        file = urllib.urlopen(request.POST['url'])
        randname = rand1(settings.RANDOM_ID_LENGTH)
        newfilename = request.POST['url'].split('/')[-1]
        ext = str(newfilename.split('.')[-1]).lower()
        im = cStringIO.StringIO(file.read()) # constructs a StringIO holding the image
        img = Image.open(im)

        filehash = checkhash(im)

        image = Uploads.objects.get(filehash=filehash)
        uuid = image.uuid

        return "%s" % (uuid)

    except Uploads.DoesNotExist:

        img.save(os.path.join(settings.UPLOAD_DIRECTORY,(("%s.%s")%(randname,ext))))
        del img

        filesize = os.stat(os.path.join(settings.UPLOAD_DIRECTORY,(("%s.%s")%(randname,ext)))).st_size
        upload = Uploads(
            ip          = request.META['REMOTE_ADDR'],
            filename    = newfilename,
            uuid        = randname,
            ext         = ext,
            path        = settings.UPLOAD_DIRECTORY,
            views       = 1,
            bandwidth   = filesize,
            source      = request.POST['url'],
            size        = filesize,
            filehash    = filehash,
        )

        upload.save()
        #return uuid
        return "%s" % (upload.uuid)
    except IOError, e:
        raise e

何か案は?

ありがとう!

ウェンバート

4

2 に答える 2

3

そのImageクラスはどこから来て、何をしImage.openますか?

私の推測では、それは画像データのある程度のサニタイズを行いますが(これは良いことです)、Gifの最初のフレームのみを保存します。

編集:

これはPILの問題であると私は確信しています。GIFのPILドキュメントには次のように書かれています。

PILは、GIFファイル形式のGIF87aおよびGIF89aバージョンを読み取ります。ライブラリは、ランレングスでエンコードされたGIF87aファイルを書き込みます。

確認するために、の内容imをディスクに直接書き込み、ソースイメージと比較することができます。

于 2011-01-10T10:49:09.510 に答える
1

問題は、PILで開いたバージョンの画像を保存することです。PILを介して保存すると、最初のフレームのみが保存されます。

ただし、簡単な回避策があります。ファイルの一時コピーを作成し、PILで開きます。次に、アニメーションGIFであることがわかった場合は、PILで開いたバージョンではなく元のファイルを保存します。

元のアニメーションGIFファイルを保存し、それをHTTP応答にストリーミングして戻すと、アニメーション化されてブラウザに送られます。

PILオブジェクトがアニメーションGIFであるかどうかを検出するためのサンプルコード:

def image_is_animated_gif(image):
    # verify image format
    if image.format.lower() != 'gif':
        return False

    # verify GIF is animated by attempting to seek beyond the initial frame
    try:
        image.seek(1)
    except EOFError:
        return False
    else:
        return True
于 2013-02-26T23:18:25.387 に答える