【问题标题】:Django download and display an image via ajaxDjango通过ajax下载并显示图像
【发布时间】:2015-12-26 18:58:31
【问题描述】:

我正在尝试为我的 views.py 创建一个 ajax 请求,该请求返回一个较大图像的裁剪片段。我遇到的问题是图像似乎没有被下载,或者至少没有被绘制。没有与之关联的错误消息,只是没有任何反应(包括“测试”未记录到控制台)。我已经在 javascript 中留下了一些尝试,但它们似乎都不起作用。

视图功能似乎也不是特别快,“调用”响应在请求后 5 秒以上打印出来。我想知道这是不是因为加载图像需要很长时间?如果是这种情况,是否有一种方法可以加快速度,即只加载一次图像并将其保存在内存中,或者只是一种更好的方法。这是一个相当大的图像(12000x6000 像素,28.5 MB JPEG)。 我知道正在调用 views.py 函数,方法是使用日志记录模块确认它。

简而言之:

  1. 为什么我的图片没有显示?
  2. 有没有更快捷的图片传送方式?

Views.py:

def test(request):
    img = Image.open(settings.STATIC_PATH + 'geogame/big_map.jpg')
    img.load()
    xpos = int(request.GET.get('xpos', ''))
    ypos = int(request.GET.get('ypos', ''))
    upper = ypos*10 - 300
    left = xpos*10 - 600
    right = xpos*10 + 600
    lower = ypos*10 + 300
    cropped_img = img.crop((left, upper, right, lower))
    logging.warn('called')

    response = HttpResponse(content_type = 'image/jpg')
    img.save(response, "JPEG")
    return response

Ajax 请求:

Game.zoom = function() {
    zoomx = Game.clickX
    zoomy = Game.clickY
    $.ajax({
        url: 'zoom/',
        data: {xpos: zoomx, ypos: zoomy},
        type: 'get',
        success: function(data) {
            //Game.zoomedImg.src = "data:image/jpg;base64,"+data
            //Game.zoomedImg.src = data;
            //console.log(Game.zoomedImg.src);
            Game.zoomedImg.onload = function() {
                console.log("load");
                Game.zoomedImg.src = "data:image/jpg;base64,"+data
            }
            //$("#" + this.zoomedImg).one("load", function() {
            //    console.log("test");
            //    Game.ctx.drawImage(Game.zoomedImg, 0, 0);
            //    }).attr("src", "data:image/jpg;base64,"+data);
            //Game.ctx.drawImage(Game.zoomedImg, 0, 0);
            console.log("hello");
            //};
        },
        failure: function(data) {
            console.log('failed to load zoomed image')
        }
    });
}

谢谢!

编辑

buffer = cStringIO.StringIO()     logging.warn('egege')
cropped_img.save(buffer, format = "JPEG")
logging.warn('ffgge')
img_str = base64.urlsafe_b64encode(buffer.getvalue())
logging.warn('leflefe')
return HttpResponse(img_str)

【问题讨论】:

  • 如果没有更多细节,这是不可能回答的。什么是游戏? zoom 事件是什么?它什么时候被调用?为什么在onload 事件中分配返回的数据 - 什么会触发?
  • Game 是一个类(我认为,我是相当新的 javascript)。用户单击 html5 画布时会调用缩放,这些坐标用于进行缩放。数据被分配给一个 onload 事件,因为我已经读过你不想分配 src 直到它完全下载并且在发生这种情况之前它不会被激活(我可能是错的)。但是我相当肯定 onload 函数根本没有被调用。
  • 但数据 加载,因为您在 Ajax 成功函数中,该函数在响应完成加载之前不会触发。在那里使用 onload 真的没有意义。
  • hmmm,删除 onload 函数会引入 NS_ERROR_NOT_AVAILABLE 错误,这就是我读到关于使用 onload 函数的地方:stackoverflow.com/questions/17049176/…
  • 您需要对响应的图像进行 base64 编码。否则,您的 ajax 响应中只会有一个大的二进制字符串。

标签: javascript python ajax django


【解决方案1】:

我相信我已经解决了这两个部分

图片需要加载到字符串缓冲区中,并在加载后进行base64编码才能下载,如下所示:

buffer = cStringIO.StringIO()
cropped_img.save(buffer, format = "JPEG")
img_str = base64.b64encode(buffer.getvalue())
return HttpResponse(img_str)

这貌似是因为裁剪动作是惰性的,需要保存才能生效。

为了加快图像加载操作的处理速度并使其单次出现,可以将以下两行移至函数的views.py文件的开头。

img = Image.open(settings.STATIC_PATH + 'geogame/big_map.jpg')
img.load()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-02
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多