2009-03-18 37 views
15

Tôi gặp vấn đề lạ, về cơ bản trong Java Graphics.drawImage() cực kỳ chậm trên một số máy tính và nhanh hơn trên các máy tính khác. Điều này không liên quan đến sức mạnh của máy tính, một số máy tính yếu hơn chạy nó tốt trong khi một số máy tính mạnh hơn dường như bị nghẹt thở ở cuộc gọi drawImage.Graphics.drawImage() trong Java cực kỳ chậm chạp trên một số máy tính nhưng nhanh hơn nhiều trên các máy khác

Nó có thể hoặc không liên quan đến chiều rộng và chiều cao, tôi có chiều rộng và chiều cao rất, rất lớn được xác định (khoảng 5000 x 2500). Tôi sẽ không nghĩ rằng đó là vấn đề ngoại trừ như tôi đã nói nó chạy trong thời gian thực tốc độ trên một số máy tính và chậm hơn trên những người khác và dường như không được gắn liền với sức mạnh tương đối của máy tính.

Cả hai máy tính đều có cùng phiên bản Java, cả hai đều sử dụng Vista. Một có 1.83ghz Core 2 Duo với RAM 1GB và đồ họa onboard (chạy mọi thứ tốt), bộ kia có bộ vi xử lý 2.53 ghz core 2 với 9600GS (driver nVidia mới nhất) và 4GB RAM và nó có nghĩa là chugs trên cuộc gọi drawImage.

Bất kỳ ý tưởng nào?

chỉnh sửa: ok điều này thực sự là khủng khiếp, tôi vẽ hình ảnh vào cửa sổ trong Swing, bây giờ khi tôi thay đổi kích thước cửa sổ và làm cho nó thực sự nhỏ hình ảnh được thu nhỏ quá và nó trở nên nhỏ. Đột nhiên tất cả mọi thứ diễn ra suôn sẻ, khi tôi mở rộng nó trở lại kích thước nó đã được trước khi nó vẫn chạy trơn tru!

Nó cũng có nhiều vấn đề về màn hình, nếu tôi thực hiện thủ thuật thay đổi kích thước để nó chạy nhanh hơn trên một màn hình, sau đó di chuyển sang màn hình khác khi hơn một nửa cửa sổ đang ở màn hình mới, nó bắt đầu chugging lại. Tôi phải thay đổi kích thước cửa sổ một lần nữa để nhỏ sau đó trở lại kích thước ban đầu của nó để lấy lại tốc độ.

Nếu tôi làm các trick thay đổi kích thước trên một màn hình, di chuyển nó qua cho người khác nó của chugs tất nhiên, nhưng nếu tôi trở lại nó trở lại màn hình ban đầu mà tôi đã làm các trick thay đổi kích thước nó hoạt động 100%

Nếu tôi có hai cửa sổ swing mở (hiển thị cùng một hình ảnh) cả hai đều chạy chậm, nhưng nếu tôi làm thủ thuật thay đổi kích thước trên một cửa sổ cả hai đều bắt đầu chạy trơn tru (tuy nhiên điều này không phải luôn luôn như vậy).

* khi tôi nói thay đổi kích thước cửa sổ, tôi có nghĩa là làm cho nó càng nhỏ càng tốt đến điểm hình ảnh không thể thực sự được nhìn thấy.

Đây có phải là lỗi trong Java không?

+0

Những loại hình ảnh là nó, và những gì phiên bản của JDK là trên các máy tính? –

+0

Tôi nghĩ rằng tôi thấy cùng một vấn đề.Đây là JDK 8 trên XP (vâng tôi biết) và màn hình Hi-Color. Phải mất một vài giây để render BufferedImage chứa một ảnh toàn màn hình - nhưng chỉ có lần thứ hai (!) Thành phần được vẽ. Các cuộc gọi tiếp theo để drawImage là ngay lập tức một lần nữa. Có thể một số chuyển đổi diễn ra trong nội bộ? Khá khó hiểu tất cả trong tất cả, và không thực sự chấp nhận được rằng một chuyển đổi màu sắc đơn giản mất nhiều thời gian (nếu đó là lý do). –

Trả lời

2

Có một vài điều mà có thể ảnh hưởng đến hiệu suất ở đây:

  • RAM sẵn
  • tốc độ CPU
  • card đồ họa (onboard hoặc riêng biệt)
  • lái xe Graphic phiên bản
  • Java
  • Chế độ video đã sử dụng (độ phân giải, bitdepth, hỗ trợ tăng tốc)

EDIT: Xem qua câu hỏi đã chỉnh sửa, tôi đề nghị kiểm tra xem hệ thống 9600GS có cài đặt trình điều khiển NVIDIA mới nhất chưa. Gần đây tôi đã cài đặt trình điều khiển cho card đồ họa tích hợp Intel thay thế trình điều khiển Windows chung và thực hiện các cửa sổ di chuyển, xem video, duyệt web, v.v. nhanh hơn rất nhiều.

Tất cả các thông số kỹ thuật khác đều tốt. Có lẽ Java không phát hiện 9600GS và không sử dụng tăng tốc phần cứng, nhưng tôi nghi ngờ điều này.

Đồng thời kiểm tra cấu hình hệ điều hành. Trên Windows, bạn có thể tắt tăng tốc phần cứng cho mục đích gỡ lỗi.

Tất nhiên cách tốt nhất để xử lý việc này là thay đổi mã của bạn - thay đổi kích thước hình ảnh hoặc chia nhỏ thành các phần như DNS được đề xuất. Bạn sẽ không bao giờ có thể xem toàn bộ hình ảnh như trên màn hình.

+0

Một máy tính cũ, chúng ta đang nói rất cũ và cái kia là mới và cao cấp, nó có CPU, RAM, đồ họa tốt hơn nhưng cùng phiên bản Java. Ngoài ra tôi có thể đã sai với 50.000x25.000, nó thực sự là 5000x2500. –

2

Bạn đánh giá thế nào về sức mạnh của máy tính? Hình ảnh 32-bit K 50x25 K mất hơn 4,5 GB RAM để lưu trong bộ nhớ (50000 * 25000 * 4 byte). Nếu một máy tính có nhiều RAM hơn một máy tính khác, điều đó có thể tạo ra sự khác biệt lớn về tốc độ, bởi vì nó sẽ không phải chuyển sang đĩa thường xuyên. Bạn nên xem xét việc lấy các phần phụ của hình ảnh và làm việc với những hình ảnh đó, thay vì toàn bộ điều đó.

Chỉnh sửa: Bạn đang sử dụng trình điều khiển đồ họa Java & mới nhất? Nếu hình ảnh của bạn chỉ là 5Kx2.5K, điều duy nhất tôi có thể nghĩ là nó làm việc đó mà không cần bất kỳ tăng tốc phần cứng nào.

+0

không, tôi có nghĩa là 5000x2000, tôi đã tìm thấy số lượng 50000x20000 khá lớn sau đó nhận ra tôi đã đặt thêm 0 vào cuối số, tôi có thể từ từ đi mù hoặc một cái gì đó. –

1

Kiểm tra cài đặt màn hình. Đặt cược của tôi là độ sâu pixel khác nhau trên hai hệ thống và độ sâu pixel có độ sâu pixel lẻ liên quan đến đối tượng hình ảnh mà bạn đang cố gắng hiển thị.

0

Vì Java uses OpenGL to do 2D drawing, hiệu suất của ứng dụng sẽ bị ảnh hưởng bởi hiệu suất OpenGL của chip đồ họa trong máy tính tương ứng. Hỗ trợ cho OpenGL đang suy giảm trong ngành công nghiệp 3D, có nghĩa là (trớ trêu thay) chip mới hơn có thể chậm hơn ở OpenGL rendering hơn so với những người lớn tuổi - không chỉ do phần cứng mà còn trình điều khiển.

4

Nếu bạn đang sử dụng Java nắng thử một số các thuộc tính hệ thống sau đây, hoặc là tham số dòng lệnh hoặc dòng đầu tiên trong chính

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

nhiều cờ có thể xem tại this page

Nhìn vào sun.java2d.trace có thể cho phép bạn xác định nguồn của hiệu suất đồ họa ít hơn mong muốn.

22

Hiệu suất ghi hình ảnh lên màn hình bị ảnh hưởng rất nhiều bởi định dạng mà hình ảnh được lưu trữ. Nếu định dạng giống như bộ nhớ màn hình muốn thì nó có thể rất nhanh; nếu nó không phải là sau đó một chuyển đổi phải được thực hiện, đôi khi pixel bằng pixel, mà là rất chậm.

Nếu bạn có bất kỳ kiểm soát nào về cách lưu trữ hình ảnh, bạn nên lưu trữ nó ở định dạng mà màn hình đang tìm kiếm. Dưới đây là một số mã mẫu:

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

Nếu bạn định vẽ hình ảnh nhiều lần, nó có thể có giá trị chuyển đổi sang định dạng tương thích ngay cả khi định dạng khác.

Vẽ một hình ảnh cũng sẽ chậm hơn nếu bạn đang chuyển đổi hình ảnh khi bạn vẽ, phần 'thay đổi kích thước' của mô tả làm cho tôi nghĩ bạn có thể là. Một lần nữa, làm thay đổi kích thước một lần (khi cửa sổ được thay đổi kích thước) và bộ nhớ cache hình ảnh được thay đổi kích thước và tương thích để nó có thể được vẽ lại nhanh chóng.

+3

điều này làm việc rực rỡ cho tôi, cảm ơn bạn! Tôi đã sử dụng mã này cùng với getRGB/setRGB để chuyển đổi BufferedImage của tôi – Sam

+1

Cảm ơn bạn! Câu trả lời tuyệt vời, đã giúp tôi rất nhiều. Hãy xem xét chấp nhận nó. –

+0

Cảm ơn bạn rất nhiều vì điều này! Đã đi từ ~ 17fps đến 40 –

Các vấn đề liên quan