2017-12-29 204 views
6

Przekształciłem obraz w tablicę pikseli. Zapisałem wartości RGB w trzech oddzielnych tablicach.Konwertuj obraz na tablicę pikseli, odtwórz obraz za pomocą pikseli - rozmiar zostanie zmniejszony. Czemu?

Następnie próbowałem utworzyć obraz przy użyciu tych samych wartości (bez manipulacji). Oryginalny obraz miał 205 kB, a nowy obraz 121 kB w przypadku obrazu B & W oraz od 215 kB do 96 kB w przypadku kolorowego obrazu. Ponadto występuje niewielka zmiana jasności (jasność się zwiększa, a także ogólny kontrast). Co to powoduje?

Próbowałem zarówno z kolorowych i B & obrazów W. Wynik był taki sam.

Również uruchomiłem ten sam kod na poprzednim obrazie wyjściowym (96kB), nowe wyjście było nadal 96kB.

Codes-


1) Aby odczytać obraz:

int width = img.getWidth(null); 
int height = img.getHeight(null); 

pixelR = new int[width * height]; 
pixelG = new int[width * height]; 
pixelB = new int[width * height]; 

int index=0; 

int r, g, b, gray, rgb; 

for(int i=0; i<width; i++) { 
    for (int j=0; j<height; j++) { 
    rgb = img.getRGB(i, j); 

    r = (rgb >> 16) & 0xFF; 
    g = (rgb >> 8) & 0xFF; 
    b = (rgb & 0xFF); 

    pixelR[index]=r; 
    pixelG[index]=g; 
    pixelB[index]=b; 
    index++; 
    } 
} 

2) Napisz do obrazu:

 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 

    int index=0; 
    int val; 
    int r, g, b; 

    for (int i=0; i<width; i++) { 
    for (int j=0; j<height; j++) { 

     r=pixelR[index]; 
     g=pixelG[index]; 
     b=pixelB[index++]; 

     Color newColor = new Color((int)r, (int)g, (int)b);  
     image.setRGB(i, j, newColor.getRGB()); 
    } 
    } 

    File f = null; 

    try{ 
    f = new File("<filepath>.jpg"); 
     ImageIO.write(image, "jpg", f); 
    }catch(IOException e){ 
     System.out.println("Error: "+e); 
    } 
    } 
+3

Być może piszesz w niższej jakości niż oryginalny obraz? –

+1

'pixelR [indeks] = r; pixelG [indeks] = r; pixelB [index] = r; 'ciągle przypisujesz tę samą wartość. Czy to literówka? – TDG

+0

@TDG tak, literówka. Poprawione. –

Odpowiedz

1

Możesz spróbować ustawić poziom kompresji na różne wartości i zobaczyć, jak rozmiar pliku zależy od tego. Zobacz, jak to zrobić: Setting jpg compression level with ImageIO in Java.

Nie wyjaśnia jednak zmiany jasności i kontrastu.

+0

Jeśli tak, czy obraz wyjściowy nie zostanie ponownie skompresowany, jeśli udostępnię obraz wyjściowy jako obraz wejściowy? Załóżmy na przykład, że obraz, ** image1 ** to 100kB, zostanie skompresowany do 60kB, gdy uruchomię program i zostanie zapisany jako ** output1 **, teraz obraz 60kB powinien zostać skompresowany ponownie, jeśli uruchomię program it i zapisz go jako ** output2 **, co nie jest przypadkiem, a ** output2 ** również 60kB. –

+0

Nie, zazwyczaj nie można kompresować wiele razy z pozytywnymi efektami (zmniejszenie rozmiaru). Jeśli tak było, możesz kompresować wiele razy z rzędu i wymyślić plik z powiedzeniem tylko jednego bajtu. Wynikowy plik nie byłby w stanie zakodować obrazu o podobnej jakości. Kompresja polega na wykrywaniu wzorców w danych i ich wydajnym kodowaniu. Dzięki wielu typowym algorytmom, nie można wykryć wzorów oszczędzających miejsce, gdy zostaną uruchomione po raz drugi na już skompresowanych danych. – sebkur

+0

Zobacz to pytanie podczas ogólnej dyskusji o kompresji danych wiele razy: https://stackoverflow.com/questions/3198666/why-can-data-be-compressed-only-once – sebkur