2012-01-08 2 views
2

Я записывал программу для захвата экрана с заданным интервалом, и когда я начал тестировать, я обнаружил, что получаю исключение OutOfMemoryException почти сразу после того, как он начинает записывать снимки. Я попытался выделить больше памяти - я дал ей 256 м, но это вряд ли помогло. Все, что он сделал, это сделать это на 2 или 3 секунды, прежде чем выбросить исключение и снова свернуть.Java: OutOfMemory с использованием Robot # createScreenCapture (Rectangle)

Я понимаю, что метод createScreenCapture (...) использует много памяти, но я видел примеры программ, которые могут записываться в течение большого количества раз с использованием того же метода - как они это делают?

Редактировать: Я использовал совет ваших ребят, и теперь я не получаю OutOfMemoryExceptions! Ура! Я взял маршрут, который включает сохранение фотографий на жесткий диск. Тем не менее, на самом деле их запись в архивный файл занимает довольно много времени. Запись 63 кадров в архивный файл занимает почти 2 минуты!

Я не могу предоставить какой-либо код, потому что я переписываю часть ввода-вывода. Работа над улучшением ситуации.

ответ

1

Я видел примеры программ, которые могут записываться на большое количество раз, используя тот же метод - как они это делают?

Сериализовать изображения на диск (в виде отдельных файлов или в один почтовый индекс).


Есть определенная процедура, я должен использовать для сохранения на жестком диске? Я думал о преобразовании изображений в массив int [], а затем просто сохранял это, так как массивы сериализуемы.

Существует ряд стратегий, которые можно преследовать.

  • Преобразование изображения в не-потерями (& легко кодировать) формат изображения и сохранить изображение как:
    1. В отдельных файлах на диске, или ..
    2. как отдельные записи в (несжатый) Zip-архив. Используя Zip, мы можем обойти ранние проблемы, о которых сообщалось при хранении «тысяч» файлов. Сделайте его несжатым для соображений скорости (и тот факт, что Zip делает очень мало для большинства медиаформатов).
  • Я когда-то видел код на usenet, который был вызван (AFAIR) «Скрины» или что-то в этом роде (не могу найти его сейчас), который так сильно понравился вам. Он хранил необработанную информацию (без какой-либо кодировки) на диск. Я пробовал код и не мог получить лучшую производительность для него, чем кодирование изображения в PNG & сериализации изображения на диск. Возможно, вы захотите запустить несколько тестов, чтобы узнать, какой из этих методов выходит быстрее.
+0

Чтобы не записывать изображение в память на всю жизнь программы, оно сохраняет его на жесткий диск? –

+0

* «Сохраняет его на жесткий диск?» * Да. –

+0

Хорошо, я посмотрю. Есть ли определенная процедура, которую я должен использовать для сохранения на жестком диске? Я думал о преобразовании изображений в массив int [], а затем просто сохранял это, так как массивы сериализуемы. –

0

90 миллисекунд - довольно короткий интервал ожидания, прежде чем щелкнуть следующую картинку. Вы, наверное, слишком много. Почему бы не установить ограничение на то, насколько большой может получить collection.

+0

Я попытался замедлить скорость вниз немного, это мало помогло. Вот почему это удивительно для меня. –

0

Thread.sleep (90) сделает вашу программу паузой в течение 90 миллисекунд. Таким образом, за 2-3 секунды требуется около 200-300 снимков, что было бы довольно много.

+0

Обычно у меня есть параметр, который позволяет пользователю выбирать, сколько изображений в секунду. Первоначально я тестировал 30 кадров в секунду (FPS), и в течение нескольких секунд у него не хватило памяти, затем я помещал его в 5 кадров в секунду, и он разбился, может быть, на секунду или два позже. –

1

Как это сохранить изображение? Насколько большой экран?Я не знаком со всеми ColorModels, поддерживаемыми BufferedImage, но в худшем случае полное изображение RGB @ 1900 x 1200 будет 1900 * 1200 * 24 бит или около 7 МБ. Даже при 5 FPS это 35 МБ в секунду, которая будет превышать 256 МБ менее чем за 10 секунд, игнорируя все другие возможности использования памяти.

Вам, скорее всего, придется записывать на диск или сжимать эти данные «на лету», но вы по-прежнему будете легко удалять ограничения по памяти.

+0

Могу ли я быстро достичь пределов, даже если бы я превратил изображения в целые массивы и записывал их на жесткий диск? –

+0

Что вы делаете с ними позже? Я предполагаю, что вы хотите что-то сыграть? Если вы пишете файлы изображений на диск, а не сохраняете их в коллекции, вы будете связаны размером диска (35 МБ в секунду будет примерно 1 ГБ за 30 секунд), поэтому у вас может быть 4 часа записи на 500 ГБ. Вы можете сжать их, если вы превращаете их в видео, просто сделайте это. Если робот, о котором вы говорите, является Xuggle, посмотрите на http://wiki.xuggle.com/MediaTool_Introduction#How_To_Take_Snapshots_Of_Your_Desktop – James

0

Вы добавляете память изображения (области) в коллекцию.

 BufferedImage image = robot.createScreenCapture(area); //OutOfMemory on this line. 
     collection.addFirst(image); 

Что бы вы ожидали, чем больше вы добавляете, тем больше оно получается.

Попробуйте записать его в файл/базу данных или удалить старый буфер изображения, чтобы сохранить буфер, возможно, 20 последних изображений.

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

Если вы делаете решения типа отслеживания с веб-камер, сообщите нам, его новый набор инструментов и понятий.

+0

Хорошо, что в настоящий момент он довольно единодушный, что мне нужно его хранить на жестком диске. –

+0

Не могли бы вы рассказать мне, чего вы пытаетесь достичь? есть много способов скинуть кошку. – Araejay

+0

По существу сделайте инструмент, который захватывает ваш экран в видеоформате. Делает много фотографий, затем конвертирует в видео с помощью JMF. –