Reputation: 21
I am trying to load this image from URL, but receive image like this.
Code:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
URL url = new URL("http://s.developers.org.ua/img/announces/java_1.jpg");
BufferedInputStream in = new BufferedInputStream(url.openStream());
byte[] b = new byte[512];
while (in.read(b)!=-1)
out.write(b);
Image img = ImageIO.read(new ByteArrayInputStream(out.toByteArray()));
g2.drawImage(img, 0, 0, getWidth(), getHeight(), null);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Upvotes: 1
Views: 1107
Reputation: 27113
Don't read images inside the paintComponent
method, it will make your application appear sluggish, as the method is executed on the event dispatcher thread (EDT). Also, it will be re-read, whenever your component is re-painted, meaning you'll download the image over and over. Instead, read it up front, or in a separate thread (ie. use a SwingWorker
), and only invoke g.drawImage(...)
from inside the paintComponent
method.
The reason for the broken image is your byte copying code, where you don't pay attention to how many bytes are read (as long as the value isn't -1
), but instead unconditionally copy 512
bytes. However, you don't need to do that here, you can simply pass the stream to ImageIO.read
, like this, making the code simpler and more readable:
URL url = new URL("http://s.developers.org.ua/img/announces/java_1.jpg");
try (BufferedInputStream in = new BufferedInputStream(url.openStream())) {
BufferedImage img = ImageIO.read(in);
}
Adding the extra try
(try-with-resources) block makes sure your stream is also properly closed to avoid resource leaks.
For completeness, to fix the byte copying code, the correct version would be:
// ... as above ...
byte[] b = new byte[512];
int bytesRead; // Keep track of the number of bytes read into 'b'
while ((bytesRead = in.read(b)) != -1)
out.write(b, 0, bytesRead);
Upvotes: 2
Reputation: 841
I don't know if this is the only problem, but you might write more than you get. I suggest that you change your writing code to:
int len;
while ((len=in.read(b))!=-1)
out.write(b, 0, len);
Otherwise, if the last buffer is not exactly 512 bytes long, you'll write too much
Upvotes: 1
Reputation: 66
I have some code copy file from URL to Local.. So far the result is same like actual source. Just do some modification maybe can help to solved it.
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import org.apache.commons.io.FilenameUtils;
import javax.imageio.ImageIO;
public class ImagesUrlToImagesLocal {
public ArrayList<String> getIt(ArrayList<String> urlFile)
{
ArrayList<String> strResult = new ArrayList<String>();
Image imagesUrl = null;
String baseName = null;
String extension = null;
File outputfile = null;
try {
for (int i = 0; i < urlFile.size(); i++)
{
URL url = new URL(urlFile.get(i));
baseName = FilenameUtils.getBaseName(urlFile.get(i));
extension = FilenameUtils.getExtension(urlFile.get(i));
imagesUrl = ImageIO.read(url);
BufferedImage image = (BufferedImage) imagesUrl;
outputfile = new File("temp_images/" + baseName + "." + extension);
ImageIO.write(image, extension, outputfile);
strResult.add("temp_images/" + baseName + "." + extension);
}
} catch (Exception e) {
e.printStackTrace();
}
return strResult;
}
}
Upvotes: 0