2012-04-20 14 views
19

Próbuję wysłać wiele obrazów za pośrednictwem gniazda przy użyciu java, ale potrzebuję szybszego sposobu konwersji obrazów na tablicę bajtów, aby móc je wysłać. Wypróbowałem poniższy kod, ale napisałem około 10 000 obrazów na dysku C: \. Czy istnieje sposób na dokonanie tej konwersji bez zapisywania na dysku? Dzięki!Konwersja Java-Convert na bajt [] bez zapisywania na dysku

ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 

        //ImageIO.setUseCache(false); 
        ImageIO.write(bi.getImage(), "jpg", outputStream); 

        byte[] imageBytes = outputStream.toByteArray(); 
+0

Zauważ, że trochę więcej czasu robi kompresji obrazu przy użyciu wyższą kompresję (niższa jakość) JPEG można zaoszczędzić dużo czasu w sieci. Myślę, że powinieneś wziąć pod uwagę rozmiar bajtów faktycznie wysłany, który będzie znacznie większy z czystym 'BufferedImage'. BTW - jakie jest źródło tych obrazów? Jeśli jest to zrzut ekranu dla np., Często PNG może zapewnić mniejszy rozmiar bajtu niż domyślny kompresyjny JPEG. Jeśli były to ciągłe zrzuty ekranu, być może nawet strumień wideo. –

+0

Źródłem są ciągłe zrzuty ekranu, które zasadniczo wprowadzam do strumienia. Ale tak, muszę wymyślić, jak skompresować obrazy bez zapisywania ich na dysku. To jest mój ostateczny cel – tier1

Odpowiedz

38

To powinno działać:

byte[] imageBytes = ((DataBufferByte) bufferedImage.getData().getDataBuffer()).getData(); 
+0

Twój ratownik życia. Dzięki! – tier1

+14

Spowoduje to utworzenie kopii obrazu. Jeśli chcesz tylko bezpośrednie odwoływanie się do bajtów, wywołaj bufferedImage.getRaster(). GetDataBuffer() i przesyłaj go odpowiednio (nie zawsze jest to bezpieczne, aby przesyłać do DataBufferByte) –

+3

to nie wydaje się działać dla mnie. Otrzymuję 'java.awt.image.DataBufferInt nie można przesyłać do java.awt.image.DataBufferByte' mój buforowany obraz pochodzi z' Robot.createScreenCapture() 'nie wiem, czy to ma znaczenie – user3712476

1

Spróbuj użyć:

ImageIO.setUseCache(false); 

Przed piśmie, może to pomoże.

+0

Próbowałem tego, jednak uważam, że to nadal zapisuje na dysku, po prostu usuwa go po zakończeniu operacji. – tier1

+0

nie powinien, przynajmniej zgodnie z dokumentami: 'Ustawienie tej flagi na false uniemożliwia użycie dysku dla przyszłych strumieni, co może być korzystne podczas pracy z małymi obrazami, ponieważ narzut tworzenia i niszczenia plików jest usuwany.". Może twój program zapisuje na dysku gdzieś indziej? – soulcheck

+0

Tak, widziałem to także w dokumentach. Tak czy inaczej, operacja jest boleśnie powolna dla tego, co chcę zrobić. W każdym razie dzięki. – tier1

1
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes)); 
byte[] bytes = new byte[buf.capacity()]; 
buf.get(bytes, 0, bytes.length); 
0

Poniższy kod to naprawdę szybko (kilka milisekund)

import com.sun.image.codec.jpeg.JPEGCodec; 
import com.sun.image.codec.jpeg.JPEGImageEncoder; 

public byte[] toByteArray(BufferedImage image) throws IOException { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream();    
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos); 
    encoder.encode(image);    
    return baos.toByteArray(); 
} 
+3

Lepiej jest trzymać się z dala od pakietu com.sun. –

Powiązane problemy