optymalizacja konwersji byte[][] do BufferedImage lub pliku

0

Witam,
szukam optymalnego rozwiązania do dokonania konwersji jak w temacie. Tablica zawiera wartości pikseli w skali szarości.

o - tablica 640x480 (np.)

BufferedImage bim = new BufferedImage o.len,480,o[0].length.TYPE_INT_RGB); //TYPE_BYTE_GRAY źle robi
for(int j=0; j<o[0].length; j++)
    for(int i=0; i<o.length; i++)
        bim.setRGB(i,j,new Color((o[i][j]& 0xFF),(o[i][j]& 0xFF),(o[i][j]& 0xFF)).getRGB());
ImageIO.write(bim,"jpg",new File("img_01//plik"+new Integer(ii).toString()+".jpg"));

Interesuje mnie:
a) metoda bezpośredniej konwersji byte[][] -> BufferedImage
b) metoda bezpośrednia byte[][] -> zapis do pliku jpg (bądź innego szybszego - nie bmp)

Każda milisekunda jest dla mnie ważna, ponieważ zasoby są na styk i i tak bede musiał robić jeszcze podójny for conajmniej ze 2 razy dla uzyskania różnych parametrów. Komp jest jednordzeniowy wiec dodatkowe wątki mi nie przyspieszą.

Są metody przyspieszające oparte na byte[] ale nie moge specjalnie konwertować bo to znów czas.

0

1.Odwróć pętle:

for(int j=0; j<o[0].length; j++)
    for(int i=0; i<o.length; i++)

na

for(int i=0; i<o.length; i++)
     for(int j=0; j<o[0].length; j++)
    

Będziesz lepiej wykorzystywał cache procesora. Możliwe, że program przyspieszy x2.

  1. tu: bim.setRGB(i,j,new Color((o[i][j]& 0xFF),(o[i][j]& 0xFF),(o[i][j]& 0xFF)).getRGB());
    wyliczaj o[i][j]& 0xFF tylko raz, btw. dlaczego "& 0xFF" jest potrzebne?
    Ponieważ u ciebie jest tylko 256 kolorów, najpierw stwórz 256 elementową tablicę zawierająca wszystkie kolory. Później zaoszczędzisz na procesorze i pamięci.
int[] kolory = new int[256];
for(int i=0;i<256;i++)
  kolory[i] = (new Color(i,i,i)).getRBG();

później:

bim.setRGB(i,j,kolory[o[i][j]);

Sprawdziłem i to co napisałem wyżej daje zysk około 15% czasu.

Jeżeli chcesz dalej przyspieszyć, to użyj drugiej wersji bim.setRGB, gdzie zapisujesz naraz całe wiersze(musisz tylko mieć int[][], nie byte[][])

Ale i tak samo ImageIO.write zajmuje około 20%.

0

Dzięki za odp :-) naprawde dobre :-) Teraz liczyłem samą pętle po2ny for ile zajmuje.
Było:
Średnio: 53ms
Min: 45ms
Max: 79ms

A teraz:
Średnio: 37ms
Min: 31ms
Max: 78ms

O ile max jest to samo to średnia spadła o 30% :-) Bardzo dobrze :-) nie pomyślałem by LUT użyć

Dalsze optymalizacje mile widziane :-) a może by tak zamiast jpg zapisywać bezpośrednio do pliku bajtowo? z headerem wymiarów?

1 użytkowników online, w tym zalogowanych: 0, gości: 1