Вопрос

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

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage = op.filter(displayImage, null);

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

op = new AffineTransformOp(atx, interactive ? interpolationInteractive : interpolationNormal);
displayImage2 = op.createCompatibleDestImage(displayImage, displayImage.getColorModel());
op.filter(displayImage, displayImage2);

Однако это намного медленнее, чем первая версия.Мне нужна скорость первой версии при использовании памяти второй.

  1. Как можно почистить после первой версии?В частности, где хранятся промежуточные BufferedImages и как их удалить?
  2. Почему вторая версия медленнее первой?Что я могу сделать, чтобы ускорить его?

Спасибо за вашу помощь!!!

Это было полезно?

Решение

Как ты поживаешь displayImage и что ColorModel оно использует?

Если это IndexColorModel, это может многое объяснить.

Первый фрагмент кода вернет BufferedImage используя DirectColorModel.Для этого потребуется 4 байта на пиксель вместо обычно 1 байта на пиксель для индексированного изображения.Расширение 1:4 может быть причиной нехватки памяти.

Второй фрагмент кода делает BufferedImage с той же моделью, что и источник.Когда это IndexColorModel и интерполяция не NEAREST_NEIGHBOR, filter() вызов создаст временный BufferedImage с DirectColorModel.Он будет использовать это как место назначения операции фильтра, затем повторно квантовать временный буфер и перерисовать его в свой displayImage2.Итак, в два раза больше битблитов.

Если вы выполняете только одно преобразование, я бы посоветовал использовать вторую форму.

Если вы выполняете несколько операций, выделите пару BufferedImageс DirectColorModel.достаточно большой, чтобы вместить самое большое изображение.Нарисуйте исходное изображение в одном из них и применяйте фильтры между ними.Затем, когда вы закончите, используйте ColorConvertOp для повторного квантования обратно в индексированное изображение.Таким образом, вам нужно будет конвертировать цвета только один раз, а не при каждом вызове фильтра.

Другие советы

Я согласен с комментарием о том, что если вы не получаете OutOfMemoryErrors, то это нормально, и сборщик мусора будет собирать изображения, когда сочтет нужным.Вот глупый тест, который я проводил иногда, когда у меня возникали опасения:поместите это в цикл в основной функции и наблюдайте за использованием памяти в профилировщике (он должен создавать зигзагообразный узор или что-то в этом роде), но не всегда сможет завершиться успешно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top