我正在尝试使用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) 该文件以某种方式被破坏。当我用Kate打开它时,我可以读到: - myboundary Content-Type:image / jpeg Content-Length:38256 .... 二进制文件中不应有任何文本。 问题是什么?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();
}
答案 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;
}
(其中imageType
是BufferedImage
声明的常量之一。很可能是TYPE_INT_RGB
。
否则你的第一种方法很好。
我建议第一种(高级)方法超过第二种(低级别)。