Как я могу сохранить JPEG из URL в файл? - PullRequest
1 голос
/ 13 февраля 2010

Я пытаюсь сохранить изображение JPEG из URL-адреса в файл с Java. 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) не могут быть <= 0» </p>

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

Файл как-то сломан. Когда я открываю его с Кейт , я могу прочитать:

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

В двоичном файле не должно быть текста.

В чем может быть проблема?

Ответы [ 2 ]

2 голосов
/ 13 февраля 2010

По какой-то причине тело ответа 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 голос
/ 13 февраля 2010

Попробуйте следующий метод для преобразования 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;
 }

(где imageType - одна из BufferedImage объявленных констант. Скорее всего TYPE_INT_RGB.

В противном случае ваш первый подход в порядке.

Я бы рекомендовал первый (высокоуровневый) подход вместо второго (низкоуровневого).

...