Graphics.drawImage () в Java чрезвычайно медленный на некоторых компьютерах и намного быстрее на других - PullRequest
15 голосов
/ 18 марта 2009

У меня странная проблема, в основном в Java Graphics.drawImage () очень медленно на некоторых компьютерах и быстрее на других. Это также не связано с питанием компьютеров: некоторые слабые компьютеры работают нормально, а некоторые более сильные, похоже, душат при вызове drawImage.

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

Оба компьютера имеют одинаковую версию Java, оба используют Vista. Один имеет 1,83 ГГц Core 2 Duo с 1 ГБ ОЗУ и встроенной графикой (все отлично работает), другой имеет 2,53 ГГц Core 2 Duo с 9600 ГС (последние драйверы nVidia) и 4 ГБ ОЗУ, и он буквально пускает вызов в вызов drawImage.

Есть идеи?

edit: ок, это действительно странно, я рисую изображение в окне в Swing, теперь, когда я изменяю размер окна и делаю его очень маленьким, изображение тоже уменьшается, и оно становится маленьким. Внезапно все идет гладко, когда я масштабирую его до размера, который был до того, как он все еще работает гладко!

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

Если я делаю трюк с изменением размера на одном мониторе, переместите его на другой, это, конечно, писк, но если я верну его обратно к исходному монитору, на котором я сделал трюк с изменением размера, он будет работать 100%

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

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

Может ли это быть ошибкой в ​​Java?

Ответы [ 7 ]

23 голосов
/ 18 марта 2009

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

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

    GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
    GraphicsDevice device = env.getDefaultScreenDevice();
    GraphicsConfiguration config = device.getDefaultConfiguration();
    BufferedImage buffy = config.createCompatibleImage(width, height, Transparency.TRANSLUCENT);
    Graphics g = buffy.getGraphics();

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

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

5 голосов
/ 18 марта 2009

Если вы используете Sun Java, попробуйте некоторые из следующих системных свойств, либо как параметры командной строки, либо как первые строки в основном

sun.java2d.opengl=true  //force ogl  
sun.java2d.ddscale=true //only when using direct3d  
sun.java2d.translaccel=true //only when using direct3d  

больше флагов можно посмотреть на этой странице

Посмотрите на sun.java2d.trace, который может позволить вам определить источник нежелательной графической производительности.

2 голосов
/ 18 марта 2009

Как вы оцениваете мощность компьютеров? Для 32-разрядного образа 50x25 K требуется более 4,5 ГБ ОЗУ для хранения в памяти (50000 * 25000 * 4 байта). Если на одном компьютере больше оперативной памяти, чем на другом, это может существенно повлиять на скорость, поскольку ему не нужно будет так часто переключаться на диск. Вам следует рассмотреть возможность захвата подразделов изображения и работы с ними вместо всего этого.

Редактировать: Вы используете последние версии драйверов Java и графики? Если ваш образ только 5Kx2.5K, я могу думать только о том, что он делает это без какого-либо аппаратного ускорения.

2 голосов
/ 18 марта 2009

Здесь есть несколько факторов, которые могут повлиять на производительность:

  • Доступная оперативная память
  • Скорость процессора
  • Графическая карта (встроенная или отдельная)
  • Графический драйвер
  • Java-версия
  • Используемый режим видео (разрешение, битовая глубина, поддержка ускорения)

EDIT: Взглянув на отредактированный вопрос, я бы предложил проверить, установлены ли в системе 9600G новейшие драйверы NVIDIA. Недавно я установил драйвер для встроенной графической карты Intel, который заменил общий драйвер Windows и сделал перемещение окон, просмотр видео, просмотр и т. Д. Намного быстрее.

Все остальные характеристики выглядят хорошо. Возможно, Java не обнаруживает 9600GS и не использует аппаратное ускорение, но я сомневаюсь в этом.

Также проверьте конфигурацию ОС. В Windows вы можете отключить аппаратное ускорение для целей отладки.

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

1 голос
/ 18 марта 2009

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

0 голосов
/ 17 февраля 2011

Вы пробовали полноэкранный эксклюзивный режим?

Это может помочь: http://download.oracle.com/javase/tutorial/extra/fullscreen/index.html

0 голосов
/ 18 марта 2009

Поскольку Java использует OpenGL для выполнения 2D-рисования , производительность вашего приложения будет зависеть от производительности OpenGL графического чипа на соответствующем компьютере. Поддержка OpenGL сокращается в 3D-индустрии, что означает, что (по иронии судьбы) более новые чипы могут быть медленнее при рендеринге OpenGL, чем старые - не только из-за аппаратного обеспечения, но и драйверов.

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