View Full Version : [Java]Copiare immagine da url Web
tonio123
12-10-2011, 18:54
Allora il mio problema è il seguente: ho un url che rappresenta l'indirizzo di un immagine di cui voglio ottenere una copia fisica su disco; la cosa più semplice che mi è venuta in mente è di trattarla come uno stream binario con il codice seguente:
URL poster=new URL(cutter.nextToken());
InputStream in=poster.openStream();
OutputStream out=new FileOutputStream("."+a.getTitle()+".jpg");
int x=in.read();
while(x>=0){
out.write(x);
x=in.read();
}
in.close();
out.close();
Ma cosi facendo mi va in un loop infinito che non capisco da cosa sia causato, perchè anche se la lascio girare per 10 minuti e poi la stacco, l'immagine risultante su disco è sempre di 17 kb, stesso risultato che ottengo se stacco dopo 20 secondi, ed è solo una parte del'originale.
Dove Sbaglio?, oppure c'è un metodo per farlo in maniera più efficiente?
P.S. un esempio di url: http://ia.media-imdb.com/images/M/MV5BMTM2ODk0NDAwMF5BMl5BanBnXkFtZTcwNTM1MDc2Mw@@._V1_SX320.jpg
Cait Sith
12-10-2011, 21:11
In un programma avevo scritto già questa funzione, non ricordo se l'avevo copiata in tutto o in parte da qualche sito.
public static void loadAndWriteImage(File dest, String src) {
try {
URL srcUrl=new URL(src);
URLConnection yc = srcUrl.openConnection();
DataInputStream in = new DataInputStream(new BufferedInputStream(yc.getInputStream()));
DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(dest)));
byte buffer;
try {
while (true) {
buffer = in.readByte();
out.writeByte(buffer);
}
} catch (EOFException e) {
}
out.flush();
out.close();
in.close();
} catch(Exception e) {
System.out.println("Si è verificato un errore durante la copia del file all'indirizzo " + src);
}
}
Il loop infinito probabilmente è dovuto a while(x>=0) che, non essendo interrotto da un catch di un eccezione, va avanti all'infinito.
E' meglio incapsulare gli stream per leggere e scrivere dei dati. Inoltre è meglio che siano bufferizzati per essere più efficienti.
Nel caso in questione apro un input stream dall'url, lo incapsulo in un buffered input stream per avere accesso bufferizzato, e poi lo incapsulo in un data input stream che è lo stream che si usa per i leggere i dati binari. Stessa cosa per il file di output, solo che l'output steam lo creo dal file.
La bufferizzazione serve perchè se leggessi un byte alla volta senza bufferizzare ci metterebbe una vita a causa dell'accesso a disco ad ogni iterazione.
tonio123
12-10-2011, 22:31
Grazie per l'aiuto, avevo messo il while >=0 perché da file quando finiva lo stream la funzione read dava come risultato -1, ma probabilmente online lo stream non finisce proprio quindi non mi dava mai il -1.
Come avrai capito è il mio primo programma che sfrutta anche solo marginalmente il web quindi sono a dir poco inesperto.
L'unica cosa che non ho capito è il passaggio per URLconnection, a cosa serve aprire da li lo stream se lo si puo fare anche da URL?
banryu79
13-10-2011, 08:56
Puoi anche usare javax.imageio.ImageIO se l'immagine è in uno dei formati supportati out-of-the-box (jpeg, png, bmp, wbmp, gif).
Ad esempio:
import javax.imageio.ImageIO;
...
// url è l'istanza URL dell'immagine
Image image = null;
try {
image = ImageIO.read(url);
} catch (IOException ex) {
// manage the i/o exception
}
...
Cait Sith
13-10-2011, 09:30
Grazie per l'aiuto, avevo messo il while >=0 perché da file quando finiva lo stream la funzione read dava come risultato -1, ma probabilmente online lo stream non finisce proprio quindi non mi dava mai il -1.
Come avrai capito è il mio primo programma che sfrutta anche solo marginalmente il web quindi sono a dir poco inesperto.
L'unica cosa che non ho capito è il passaggio per URLconnection, a cosa serve aprire da li lo stream se lo si puo fare anche da URL?
Credo che non ci sia differenza, se apri lo stream direttamente dall'url java apre una connessione e ne ritorna lo stream associato.
Comunque in effetti per le immagini è più semplice usare l'ImageIO. Invece la parte di codice che ti ho riportato io volendo si può usare per qualsiasi tipo di file.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.