如何将URL从URL保存到文件?

时间:2010-02-13 08:39:47

标签: java image url jpeg

我正在尝试使用Java将JPEG图像从URL保存到文件。 网址:http://150.214.222.100//axis-cgi/mjpg/video.cgi?resolution=640x480&compression=1&duration=1&timeout=&dummy=garb

我尝试了以下内容: 1)

Image image = fetchImage(urlNorthView);

saveImage2Disk(image);

public static Image fetchImage( URL u ) throws MalformedURLException, IOException   {
      Toolkit tk = Toolkit.getDefaultToolkit();
      return tk.createImage(u );
}

private void saveImage2Disk(Image Image) throws IOException{
        File outputFile = new File("urlNorthView"+Calendar.getInstance().getTimeInMillis()+".jpg");

        BufferedImage bufferedImage = new BufferedImage(Image.getWidth(null),Image.getHeight(null), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = bufferedImage.createGraphics();
        g2.drawImage(Image, null, null);
        ImageIO.write(bufferedImage, "jpg", outputFile);
    }

=>例外:“宽度(-1)和高度(-1)不能是

2)

inputStream2Disk((InputStream) urlNorthView.getContent());

private void inputStream2Disk(InputStream in) throws Exception{
        File outputFile = new File("urlNorthView"+Calendar.getInstance().getTimeInMillis()+".jpg");
        OutputStream out=new FileOutputStream(outputFile);
        byte buf[]=new byte[1024];
        int len;
        while((len=in.read(buf))>0)
        out.write(buf,0,len);
        out.close();
        in.close();
    }

该文件以某种方式被破坏。当我用Kate打开它时,我可以读到:

  

- myboundary Content-Type:image / jpeg Content-Length:38256 ....

二进制文件中不应有任何文本。

问题是什么?

2 个答案:

答案 0 :(得分:2)

由于某种原因,请求该图像时的http响应主体包含一个mime部分(mime部分对于将多个文件放入单个响应非常有用)。在这个响应中,只有一个哑剧部分,所以它几乎没用。

javax.mail包中有代码,如果你愿意,你可以用它来正确地解析它,但它不是一个非常好的api,imho。

或者,有很多方法可以自己解决这个问题。由于只有一个mime部分,你可以从输入流的开头扔掉数据,直到你看到一行中有两个换行符(字节等于10)。这应该工作,因为mime头应该是7位ascii,iirc,所以没有担心的字符编码。

以下是一些示例代码:

URLConnection conn = urlNorthView.openConnection();
InputStream in = conn.getInputStream();
String contentType = conn.getHeaderField("Content-Type");
if (!"image/jpeg".equals(contentType)) {
    // hack: assuming it's mime if not a raw image
    int one = in.read();
    if (one == -1) {
        // stop??
    }
    int two = in.read();
    while (two != -1 && !(two == 10 && one == 10)) {
        one = two;
        two = in.read();
    }
}
// if it was mime, we've stripped off the mime headers
// and should now get the image
inputStream2Disk(in);

编辑:废话,而不是两个\ n,你会看到两个\ r \ n,或者字节0x0d,0x0a,0x0d,0x0a。扔掉数据,直到你看到这种模式留给读者作为练习;)

答案 1 :(得分:1)

尝试使用以下方法将Image转换为BufferedImage

private static BufferedImage getBufferedImage(Image img, int imageType) {
    if (img instanceof BufferedImage) {
        return (BufferedImage) img;
    }

     BufferedImage bi = new BufferedImage(img.getWidth(null), img
             .getHeight(null), imageType);

     Graphics2D g = (Graphics2D) bi.getGraphics();
     g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
             RenderingHints.VALUE_ANTIALIAS_ON);

     g.drawImage(img, 0, 0, null);
     g.dispose();

     return bi;
 }

(其中imageTypeBufferedImage声明的常量之一。很可能是TYPE_INT_RGB

否则你的第一种方法很好。

我建议第一种(高级)方法超过第二种(低级别)。