Graphics.drawImage() в Java EXTREMELY медленнее на некоторых компьютерах, но намного быстрее на других

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

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

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

Любые идеи?

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

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

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

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

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

Возможно, это может быть ошибка на Java?

Ответы

Ответ 1

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

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

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

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

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

Ответ 2

Если вы используете 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, который позволит вам определить источник менее желательной производительности графики.

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

Ответ 5

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

Ответ 6

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