нарисовать изображение или нарисовать заполненный круг? - PullRequest
1 голос
/ 28 сентября 2010

У нас есть старое приложение Java Swing.нам нужно отобразить тысячи, сотни тысяч маленьких круговых пятен на холсте на основе реальных данных.Прямо сейчас у нас есть файл изображения небольшого пятна круга.Когда нам это нужно, мы рисуем это изображение на холсте тысячи, сотни тысяч раз.

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

как насчет вашего мнения?

спасибо,

Ответы [ 6 ]

1 голос
/ 06 октября 2010

Время вашего кода

Совершенно определенно быстрее нарисовать изображение много раз, чем нарисовать круг или строку много раз, и это очень легко проверить. В начале вашего метода paintComponent () добавьте строку:

paintComponent(){
   long start = System.currentTimeMillis();

   ...
   // draw 100,000 circles as images or circles
   ...


   System.out.println("Rendering time: " + 
             (start - System.currentTimeMillis()) + " ms");
}

Если время все время оказывается равным нулю, вместо этого вы можете использовать System.nanoTime ().

Краска в кэшированное изображение

Еще одна вещь, которую вы можете сделать, это нарисовать эти круги на изображении и воссоздать изображение только при изменении содержимого. Если ничего не изменилось, просто нарисуйте это изображение на объекте Graphics2D вместо перерисовки всех кругов. Это обычно называется двойной буферизацией. Вы также можете использовать Volatile Images , чтобы воспользоваться аппаратным ускорением.

Создание совместимых изображений

Вы также должны убедиться, что используете изображения, совместимые с монитором пользователя, с помощью createCompatibleImage (), как показано ниже:

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();

// Create an image that does not support transparency
BufferedImage bimage = gc.createCompatibleImage(width, height, Transparency.OPAQUE);

// Create an image that supports transparent pixels
bimage = gc.createCompatibleImage(width, height, Transparency.BITMASK);

// Create an image that supports arbitrary levels of transparency
bimage = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT);

Дополнительные советы

Я бы порекомендовал книгу Грязные богатые клиенты . У этого есть много хороших подсказок для ускорения колебания. Особенно обратите внимание на главы 4 и 5 об изображениях и производительности.

1 голос
/ 28 сентября 2010

Почти наверняка гораздо быстрее держать одно изображение и рисовать его много раз, чем звонить, чтобы нарисовать закрашенный круг. Вот недавняя презентация на эту тему, показывающая, что нарисовать изображение быстрее, чем даже простой горизонтальный крест. http://developers.sun.com/learning/javaoneonline/j1sessn.jsp?sessn=TS-4170&yr=2009&track=javase

1 голос
/ 28 сентября 2010

Вам нужно только один раз загрузить изображение шаблона, удерживать его в памяти и при необходимости скопировать на холст, используя функцию draw2mage Graphics2D.Рисование нескольких заполненных кругов может стать дорогим из-за вызовов алгоритма Flood-fill / Scan-fill , а также Bresenham для рисования круга.Для оптимизации рендеринга вы также можете десятичный результат рендеринга или выполнить кластеризацию , так как пользователь все равно не оценит плотные перекрывающиеся круги.

Чтобы уменьшить тест вызовов рендерингапиксель, куда идет ваш шаблон, и пропустите рендер, если он уже раскрашен.

Вот хороший апплет для сравнения .

0 голосов
/ 28 сентября 2010

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

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

0 голосов
/ 28 сентября 2010

Третий способ сделать это - использовать символ Юникода для заполненного круга, ● так как вы можете поспорить, что рендеринг тысяч символов (например, фрагмента текста) является наиболее нормальнойдля любого графического движка.

0 голосов
/ 28 сентября 2010

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

...