2012-02-28 1 views
2

Недавно я столкнулся с проблемой с проектом Django и использованием памяти в WebFaction.Обрезка изображения в Django вызывает значительное увеличение памяти

Вот два запущенные процессы в памяти для этого проекта на webfaction:

30396 4-20:20:00 13486 
30404 4-20:20:00 13487 

После зрения запустить один из процессов, существенно возрастет:

69720 4-20:20:22 13486 
30404 4-20:20:22 13487 

Как вы можете видеть первый процесс более чем удваивается в использовании памяти! Поскольку эта функция будет использоваться часто, мне нужно выяснить, что происходит. Я считаю, что я сузил его до следующего вида (это трехэтапный процесс загрузки изображения, добавления деталей, обрезки миниатюр).

Вот вид ниже. Он получает объект фотографии, загружает изображение из файла, получает полевые координаты, которые пользователь отправил, а затем создает изображение размером 200 200 пикселей. Это вновь созданное изображение записывается обратно на диск с миниатюрным именем в файле и сохраняется фотообъект.

@login_required 
def upload3(request, photo_pk): 
    photo = get_object_or_404(Photo, pk=photo_pk, user=request.user) 
    if request.method == "POST": 
     form = upload3Form(request.POST) 
     if form.is_valid(): 
      im = Image.open(photo.image.path) 
      try: 
       box =(form.cleaned_data['x1'],form.cleaned_data['y1'],form.cleaned_data['x2'],form.cleaned_data['y2']) 
      except: 
       box = ('0','0','1000','1000') 
      cropped = im.crop(box) 
      cropped.thumbnail((200,200),Image.ANTIALIAS) 
      result = os.path.splitext(photo.image.path) 
      cropped.save(result[0] + '.thumbnail' + result[1]) 
      photo.status = 3 
      photo.save() 

Любые идеи о том, что я могу делать неправильно, будем очень благодарны.

Update 1: Изображения, используемые для тестирования, все Jpeg и имеют размеры около 3600 x 2700 и составляют около 2 МБ на изображение.

+0

Сузились ли вы, какая операция в представлении приводит к увеличению использования памяти? Что произойдет, если просмотр вызывает несколько раз? –

+0

Нет У меня нет, так как я не могу делать столько отладки на реальном сервере (например, pdb). Кажется, что это не происходит каждый раз при вызове вида, но чаще всего. (После того как я загрузил несколько изображений за несколько недель, использование памяти превысило 112 мб на один процесс). – Fernker

+0

Не могли бы вы изменить свой вопрос с типичным размером и форматом изображения? –

ответ

0

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

На каждом объекте, содержащем объект изображения, используемый в PIL, мне пришлось удалить объект, как только я закончил с ним. Так, например:

im = Image.open(photo.image.path) 
try: 
    box =(form.cleaned_data['x1'],form.cleaned_data['y1'],form.cleaned_data['x2'],form.cleaned_data['y2']) 
except: 
    box = ('0','0','1000','1000') 
cropped = im.crop(box) 
newimage = cropped.resize((form.cleaned_data['dw'],form.cleaned_data['dh']),Image.ANTIALIAS) 
del im 
del cropped 

Итак, как только я закончил с объектом, я вызываю del на этот предмет. Кажется, что проблема была решена. У меня больше нет памяти, и я не могу быть счастливее.

+0

было бы намного лучше, если бы вы обновили свой вопрос с помощью решения, которое вы нашли, вместо того, чтобы отвечать на свой вопрос и отменили принятие моего ответа. –

+0

Я чувствую, что мой был более полным ответом, и когда люди приходят к вопросу, они больше смотрят на зеленый флажок, чем на обновление исходного вопроса. Я все еще дарил тебе щедрость ... – Fernker

2

Рисунок 2M предназначен для сжатого изображения JPEG, но несжатый, 3600 x 2700 truecolor будет около 38M (9,720,000 пикселей при 4B на пиксель), что близко к увеличению использования памяти, которое вы испытываете.

Это известная проблема с PIL, я могу создать пиксельную бомбу, отправив вам черно-белое изображение 40000x40000 в виде png. Всегда проверяйте разрешение перед загрузкой (или защищайте код с помощью процедуры try/except Block OutOfMemory). Посмотрите, использует ли атрибут im.tile обработку фрагмента изображения куском, что дает вам меньший объем памяти.

Может быть стоит проверить:

Некоторые альтернативы, которые, как говорят, лучше память ручки при работе с большими изображениями:

  • GDAL (геопространственных Библиотека абстракции данных)
  • OIIO (OpenImageIO)
  • Mahotas (NumPy)

[обновление]

Знаете ли вы, если есть способ в PIL, чтобы освободить объекты из памяти? Потому что теоретически это было бы лучше всего для этой точки зрения, поскольку мне нужно, чтобы она работала так, как она есть, но просто лучше обрабатывайте изображение.

  • Для того, чтобы избежать памяти спайки вы можете обнаружить огромные изображения и обрабатывать их в куски, используя im.tile вместо im.crop (к сожалению, работает на более низком уровне).
  • Вы можете удалить промежуточные объекты изображения как можно скорее, чтобы получить более короткие всплески (с помощью gc module вы можете принудительно очистить сборщик мусора).
+0

О, это имеет смысл, я бы никогда не думал о том, что фотографии сжаты. Я начал больше смотреть на то, что вы предложили, и я посмотрю, работают ли они. Знаете ли вы, есть ли способ в PIL выпустить объекты из памяти? Потому что теоретически это было бы лучше всего для этой точки зрения, поскольку мне нужно, чтобы она работала так, как она есть, но просто лучше обрабатывайте изображение. Благодарю. – Fernker

+0

Извините, я не знал, что вы обновили свой ответ. Благодарим вас за ответ, поскольку вы рассказали о том, что вызывает всплеск памяти. (Это был мой вопрос). Я собираюсь поговорить с WebFaction, чтобы узнать, есть ли у них какие-либо идеи, поскольку у меня есть достойная идея обходного решения, которое не потребует нескольких часов работы с моей стороны. – Fernker

 Смежные вопросы

  • Нет связанных вопросов^_^