2012-04-10 45 views
7

Cách nhanh nhất để nhận giá trị RGB của mỗi pixel của BufferedImage là gì?Cần cách nhanh hơn để nhận giá trị RGB cho mỗi Pixel của Ảnh đệm

Hiện tại tôi đang nhận giá trị RGB sử dụng hai vòng for như được hiển thị trong mã bên dưới, nhưng mất quá nhiều thời gian để có được các giá trị đó khi vòng lặp lồng nhau chạy tổng cộng 479999 lần cho hình ảnh của tôi. Nếu tôi sử dụng hình ảnh 16 bit, con số này sẽ cao hơn nữa!

Tôi cần một cách nhanh hơn để có được giá trị pixel.

Đây là mã Tôi hiện đang cố gắng để làm việc với:

BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg")); 

int countloop=0; 

for (int x = 0; x <bi.getWidth(); x++) { 
    for (int y = 0; y < bi.getHeight(); y++) { 
     Color c = new Color(bi.getRGB(x, y)); 
     System.out.println("red=="+c.getRed()+" green=="+c.getGreen()+" blue=="+c.getBlue()+" countloop="+countloop++);                                     
    } 
} 
+0

'nó thậm chí có thể tăng lên khi nào tôi sẽ sử dụng 16 bit image' - Tại sao các số lần lặp phụ thuộc vào bit trên mỗi pixel? Và trường hợp sử dụng cho điều đó là gì? Lưu ý rằng việc tạo các đối tượng 'Color' cũng như in ra bàn điều khiển sẽ mất một lúc. Nếu bạn muốn truy cập tất cả 479999 pixel, bạn không thể loại bỏ vòng lặp (bạn có thể hợp nhất chúng với nhau nhưng điều đó không tạo nên sự khác biệt lớn). – Thomas

+2

Đầu ra làm chậm toàn bộ vòng lặp xuống. Hãy thử nó mà không cần. –

+2

Nó có thể đi nhanh hơn rất nhiều nếu không có println –

Trả lời

12

Tôi không biết nếu điều này có thể giúp đỡ và tôi đã không kiểm tra nó chưa nhưng bạn có thể nhận được các giá trị rgb theo cách này:

BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg")); 
int[] pixel; 

for (int y = 0; y < bi.getHeight(); y++) { 
    for (int x = 0; x < bi.getWidth(); x++) { 
     pixel = bi.getRaster().getPixel(x, y, new int[3]); 
     System.out.println(pixel[0] + " - " + pixel[1] + " - " + pixel[2] + " - " + (bi.getWidth() * y + x)); 
    } 
} 

Như bạn thấy bạn không cần phải khởi tạo một màu mới bên trong vòng lặp. Tôi cũng đảo ngược các chiều rộng/chiều cao vòng như đề xuất bởi onemasse để lấy truy cập từ dữ liệu tôi đã có.

2

Bạn hãy thử BufferedImage.getRGB(int, int ,int ,int, int[] , int , int)?

Cái gì như:

int[] rgb = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(), new int[bi.getWidth() * bi.getHeight(), bi.getWidth()]) 

Chưa thử, vì vậy không chắc chắn nếu nó nhanh hơn.

chỉnh sửa Đã xem @ mã, có thể không, nhưng đáng để chụp.

3

Bạn nên lặp lại các hàng trong vòng ngoài và các cột ở bên trong. Bằng cách đó, bạn sẽ tránh được các lỗi cache.

+2

Đó không phải là những gì anh ấy đã làm? – Singh

5

Bằng cách thay đổi từ một nhóm getRGB riêng lẻ thành một getRGB lớn để sao chép toàn bộ hình ảnh thành một mảng, thời gian thực hiện giảm xuống từ 33.000 mili giây đến 3.200 mili giây, trong khi thời gian tạo mảng chỉ 31 mili giây.

Không nghi ngờ gì nữa, một người đọc lớn vào mảng và lập chỉ mục trực tiếp của mảng nhanh hơn nhiều lần đọc riêng lẻ.

Sự khác biệt hiệu suất xuất hiện liên quan đến việc sử dụng câu lệnh breakpoint ở cuối lớp. Trong khi điểm ngắt nằm ngoài vòng lặp, mọi dòng mã trong lớp dường như được kiểm tra cho điểm ngắt. Thay đổi để nhận được cá nhân không cải thiện tốc độ.

Vì mã vẫn đúng, phần còn lại của câu trả lời vẫn có thể được sử dụng.

Cũ đọc tuyên bố

colorRed=new Color(bi.getRGB(x,y)).getRed(); 

đọc tuyên bố để sao chép một hình ảnh chút vào một mảng

int[] rgbData = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(), 
       null, 0,bi.getWidth());   

Các getRGB vào một mảng đặt tất cả 3 giá trị màu thành một phần tử mảng duy nhất, màu sắc rất cá nhân phải được trích xuất bằng cách xoay và "và". Tọa độ y phải được nhân với chiều rộng của hình ảnh.

Mã để đọc màu sắc cá nhân ra khỏi mảng

colorRed=(rgbData[(y*bi.getWidth())+x] >> 16) & 0xFF; 

colorGreen=(rgbData[(y*bi.getWidth())+x] >> 8) & 0xFF; 

colorBlue=(rgbData[(y*bi.getWidth())+x]) & 0xFF; 
0

Tôi tìm thấy một giải pháp ở đây https://alvinalexander.com/blog/post/java/getting-rgb-values-for-each-pixel-in-image-using-java-bufferedi

BufferedImage bi = ImageIO.read(new File("C:\\images\\Sunset.jpg")); 

for (int x = 0; x < bi.getWidth(); x++) { 
    for (int y = 0; y < bi.getHeight(); y++) { 
     int pixel = bi.getRGB(x, y); 
     int red = (pixel >> 16) & 0xff; 
     int green = (pixel >> 8) & 0xff; 
     int blue = (pixel) & 0xff; 
     System.out.println("red: " + red + ", green: " + green + ", blue: " + blue);                                     
    } 
} 
+0

là một thuật toán nhanh hơn? –

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