AffineTransformOp скорость / память вопрос - PullRequest
0 голосов
/ 03 декабря 2009

Я задавал этот вопрос раньше, но я хотел перефразировать / уточнить некоторые моменты и расширить его. У меня есть кусок кода, который преобразует 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. Почему вторая версия медленнее первой? Что я могу сделать, чтобы ускорить его?

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

Ответы [ 2 ]

0 голосов
/ 04 декабря 2009

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

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

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

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

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

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

0 голосов
/ 03 декабря 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...