2011-07-26 20 views
8

Przepraszam za wszelką ignorancję, ale nigdy wcześniej nie pracowałem z obrazami jpeg (nie mówiąc już o wszelkiego rodzaju obrazach) w Javie.Programowe zmniejszanie rozmiaru pliku JPEG

Załóżmy, że chcę wysłać obraz jpeg z usługi sieciowej do klienta. Czy jest jakiś sposób, że mogę zmniejszyć rozmiar pliku jpeg, manipulując w jakiś sposób profilem kolorów obrazu?

Byłem już w stanie zmniejszyć rozmiar obrazu poprzez skalowanie go za pomocą zgrabnego narzędzia dla BufferedImages o nazwie imgscalr. Zobacz here.

Chciałbym również jpeg, który ma mniej kolorów niż wysokiej jakości obraz jpeg. Na przykład chciałbym móc używać koloru 8-bitowego w moim jpeg zamiast koloru 16-bitowego.

Co dokładnie powinienem zmienić, jeśli mam buforowany obraz 2D z pakietu Java?

Odpowiedz

4

Innym sposobem na zmniejszenie rozmiaru obrazu jest zmiana poziomu kompresji. Możesz to zrobić za pomocą ImageWriter.

ImageWriter writer = null; 
    Iterator<ImageWriter> iwi = ImageIO.getImageWritersByFormatName("jpg"); 
    if (!iwi.hasNext()) 
     return; 
    writer = (ImageWriter) iwi.next(); 
    ImageWriteParam iwp = writer.getDefaultWriteParam(); 
    iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT) ; 
    iwp.setCompressionQuality(compressionQuality); 
    writer.setOutput(...); 
    writer.write(null, image, iwp); 
+0

Witam, jaki wpływ (wizualnie) zmieni kompresja jpeg? Dziękujemy – Joeblackdev

+1

Spójrz na ten post http: //www.codinghorror.com/blog/2006/07/a-porównanie-jpeg-kompresja-poziomy-i-rekompresja.html –

+0

Będę się bliżej przyjrzeć, dzięki za link. Zastanawiam się jednak, czy istnieje sposób (używając obrazów w tym łączu), aby powiedzieć, że używasz mniej kolorów w jpeg? Na przykład, aby użyć koloru 8-bitowego zamiast 16-bitowego? Dzięki – Joeblackdev

1

Najprostszym sposobem na to jest rozpakowanie strumienia bajtów do obrazu Java, ewentualnie zmiana rozmiaru (co powoduje, że jest on mniejszy), a następnie ponowne wygenerowanie z tego obrazu JPEG z pożądanym ustawieniem jakości.

Ten nowy obraz jest następnie przesyłany do klienta.

+0

Dzięki za to, ale to jest dokładnie to, co do tej pory. Używam narzędzia o nazwie imgscalr do zmiany rozmiaru obrazu jpeg przed wysłaniem go do klienta. Chciałbym jednak również zaktualizować profil kolorów jpeg, aby zmniejszyć kolory w jpeg. Przez "redukcję" rozumiem użycie mniejszej ilości kolorów. Nie jestem pewien terminologii tego ... – Joeblackdev

1

Zobacz klasę ImageIO. Co do zmniejszania rozmiaru pliku: ponieważ obraz byłby już obrazem JPEG, jedyne, co możesz zrobić, to zmniejszyć jakość lub rozmiar obrazu.

Jeszcze jedna rzecz, o której należy pamiętać: jeśli obraz ma format jpeg CMYK, może być większy. Niestety, ImageIO nie może obsłużyć tych, ale możesz spróbować JAI ImageIO konwertować z CMYK na RGB (który powinien być znacznie mniejszy).

1

Dwa z możliwych rozwiązań jest zmniejszenie rozdzielczości obrazu, oto jak chcesz to zrobić:

BufferedImage original = //your image here 
scaled = original.getScaledInstance(finalWidth, finalHeight, Image.SCALE_SMOOTH); // scale the image to a smaller one 

BufferedImage result = new BufferedImage(finalWidth, finalHeight, original.getType()); 
Graphics2D g = result.createGraphics();  

g.drawImage(scaled, 0, 0, null); //draw the smaller image 
g.dispose(); 

Oczywiście, trzeba obliczyć skalowany szerokość i wysokość, więc obraz pozostaje przez to samo współczynnik proporcji.

Po narysowaniu go zmniejszyć, można obrócić obraz w pliku JPEG:

BufferedImage image = // this is the final scaled down image 

JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(output); 
JPEGEncodeParam jpegEncodeParam = jpegEncoder.getDefaultJPEGEncodeParam(image); 

jpegEncodeParam.setDensityUnit(JPEGEncodeParam.DENSITY_UNIT_DOTS_INCH); 
jpegEncodeParam.setXDensity(92); 
jpegEncodeParam.setYDensity(92); 

jpegEncodeParam.setQuality(0.8F , false); 
jpegEncoder.encode(image, jpegEncodeParam); 

Klasy te są od JAI opakowaniu (dokładniej com.sun.image.codec. jpeg), a JVM może narzekać, że nie powinny być używane bezpośrednio, ale możesz to zignorować.

Możesz pobrać JAI z here, jeśli to nie działa, mam zainstalowane mirrory github dla dwóch bibliotek: JAI core i JAI ImageIO.