Java的。来自URL的破碎图像

时间:2016-04-18 10:15:00

标签: java swing io javax.imageio

我正在尝试从网址加载此image,但会收到this之类的图片。

代码:

@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();
            }

3 个答案:

答案 0 :(得分:2)

  1. 不要在paintComponent方法中读取图像,它会使您的应用程序显得迟钝,因为该方法在事件调度程序线程(EDT)上执行。此外,无论何时重新绘制组件,都会重新阅读,这意味着您将反复下载图像。相反,请在前面或单独的线程中阅读(即使用SwingWorker),并仅从g.drawImage(...)方法内部调用paintComponent

  2. 图像损坏的原因是您的字节复制代码,您不必注意读取的字节数(只要值不是-1) ,而是无条件地复制512个字节。但是,您不需要在此处执行此操作,您只需将流传递到ImageIO.read,就像这样,使代码更简单,更易读:

    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);
    }
    

    添加额外的try(try-with-resources)块可确保您的流也已正确关闭,以避免资源泄漏。

  3. 为了完整起见,要修复字节复制代码,正确的版本是:

    // ... 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);
    

答案 1 :(得分:1)

我不知道这是否是唯一的问题,但你写的可能比你得到的多。 我建议您将编写代码更改为:

store.suspendAutoSync();
    store.removeAt(this.rowIndex);
    this.getView().getStore().sync({
        success:function(){
            ...
        },
        failure:function(){
            ...
        }
    });

否则,如果最后一个缓冲区不是512字节长,那么你会写得太多

答案 2 :(得分:0)

我有一些从URL到Local的代码复制文件。到目前为止,结果与实际来源相同。只是做一些修改可能有助于解决它。

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;
    }
}