2015-12-26 3 views
2

Я пытаюсь создать запрос ajax для своих views.py, который возвращает отрезанный сегмент большего изображения. Проблема, с которой я сталкиваюсь, заключается в том, что изображение, похоже, не загружается или, по крайней мере, не рисуется. С ним не связано сообщение об ошибке, просто ничего не происходит (в том числе «тест» не регистрируется на консоли). Я оставил несколько своих попыток с помощью javascript, но никто из них, похоже, не работал.Django загрузить и отобразить изображение через ajax

Функция просмотра также не кажется особенно быстрой, когда отклик «вызываемого» печатается через 5 секунд после запроса. Мне интересно, если это потому, что загрузка изображения длится много времени? Если это так, есть способ ускорить это, то есть только загрузить изображение один раз и сохранить его в памяти или просто лучше сделать это. Это довольно большое изображение (12000x6000 пикселей, 28,5 МБ 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') 
     } 
    }); 
} 

Спасибо!

EDIT

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) 
+0

Ответ невозможно без дополнительной информации. Что такое игра? Что такое событие 'zoom'? Когда это вызвано? Почему вы назначили возвращенные данные в событии 'onload' - что бы это вызвало? –

+0

Игра - это класс (я думаю, я довольно новый javascript). zoom вызывается при нажатии пользователем на холст html5, эти координаты используются для масштабирования. Данные были назначены событию onload, потому что я прочитал, что вы не хотите назначать src, пока он не будет полностью загружен, и это не активируется до тех пор, пока это не произойдет (я мог ошибаться). Однако я уверен, что функция onload не называется вообще. –

+0

Но данные * загружены, потому что вы находитесь в функции успеха Ajax, которая не срабатывает, пока реакция не завершится. На самом деле не имеет смысла использовать onload там. –

ответ

0

Ну, я считаю, что я решил обе части

Изображение должно быть загружено в буфер строк и base64, закодированные для загрузки после загрузки следующим образом:

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

Это, по-видимому, потому, что действие урожая является ленивым и должно быть сохранено до его вступления в силу.

Кроме того, чтобы ускорить процесс загрузки изображения и сделать его единственным, следующие две строки можно перенести в начало файла views.py OUTSIDE.

img = Image.open(settings.STATIC_PATH + 'geogame/big_map.jpg') 
img.load() 
Смежные вопросы