web2jpg.jar -a 0.5625 "http://www.google.co.jp" "sshot.jpg"
な感じ
jarとライブラリとソース
http://sorr.biz/spinouts/web2jpg.zip
オプション
- a アスペクト比
- cw キャプチャする(大体の)横幅
- tw jpgの横幅
- d キャプチャするまでのdelay
左上に小さくウィンドウが一瞬出てしまうのがウザいが、出さずにうまくやる方法がわからなかった
レンダリングの完了を知る方法もわからず…というか手を入れるのが大変そうだったので適当なdelay後にキャプチャすることにした
ブラウザとしての再現性には難がある
特にCSSは厳密に解釈するだとかで全然まともに動かない
jsも文字コード周りでよく死ぬっぽい
しかしものすごく簡単にこんなことができるので、もちっとパーサとレンダラの精度が上がってくるとマジで実用になりそう
package biz.sorr.web2jpg; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.util.logging.*; import javax.imageio.ImageIO; import javax.swing.*; import org.lobobrowser.html.gui.*; import org.lobobrowser.html.test.*; public class Web2jpg { private String uri; private String filename; private int captureWidth; private int captureHeight; private int thumbWidth; private int thumbHeight; private double aspectRate; private int delay; private JFrame window; private HtmlPanel panel; public static void main(String[] args) { new Web2jpg(args); } Web2jpg(String[] args){ argProcess(args); if(null == uri) return; if(null == filename) return; if(aspectRate <= 0){ aspectRate = 0.75; } if(captureWidth <= 0){ captureWidth = 800; } if(thumbWidth <= 0){ thumbWidth = 240; } if(delay <= 0){ delay = 5000; } captureHeight = (int)(captureWidth * aspectRate); thumbHeight = (int)(thumbWidth * aspectRate); System.out.println("uri->" + uri); System.out.println("filename->" + filename); System.out.println("acpectRate->" + aspectRate); System.out.println("captureWidth->" + captureWidth); System.out.println("captureHeight->" + captureHeight); System.out.println("thumbWidth->" + thumbWidth); System.out.println("thumbHeight->" + thumbHeight); System.out.println("delay->" + delay); try{ Logger.getLogger("org.lobobrowser") .setLevel(Level.WARNING); window = new JFrame(); window.setVisible(true); window.setVisible(false); panel = new HtmlPanel(); window.getContentPane().add(panel); window.setSize(captureWidth, captureHeight); window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); new SimpleHtmlRendererContext(panel, new SimpleUserAgentContext()) .navigate(uri); }catch(Exception ex){ ex.printStackTrace(); } DummyWait dw = new DummyWait(); Thread dummyWait = new Thread(dw); dummyWait.start(); try { dummyWait.join(); } catch (Exception ex) { ex.printStackTrace(); } } private void Capture(){ System.out.println("Capture()"); try { BufferedImage image = new BufferedImage( panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB ); BufferedImage thumb = new BufferedImage(thumbWidth, thumbHeight, BufferedImage.TYPE_INT_RGB ); Graphics2D g2d = image.createGraphics(); panel.paint(g2d); //http://yusuke.homeip.net/diary/2006/02/09/1139476974993.html g2d = thumb.createGraphics(); g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE); g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON); g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); g2d.drawImage(image, 0, 0, thumbWidth, thumbHeight, null); g2d.dispose(); ImageIO.write( thumb, "jpeg", new File( filename ) ); } catch ( Exception ex) { ex.printStackTrace(); } } private class DummyWait implements Runnable { public void run() { try { Thread.sleep(delay); } catch (InterruptedException e) { System.out.println(e); } Capture(); window.dispose(); } } private void argProcess(String[] args){ String id; String val; for(int i = 0, i_n = args.length; i < i_n; i++){ id = args[i]; if('-' == id.charAt(0)){ if(i == args.length - 1) break; val = args[i+1]; if(id.equals("-a") || id.equals("-A")){ try{ aspectRate = Double.parseDouble(val); }catch(Exception ex){ System.out.println("invalid value->" + id); ex.printStackTrace(); } }else if(id.equals("-cw")){ int a = Integer.getInteger(val, 0); if(0 != a){ captureWidth = a; }else{ System.out.println("invalid value->" + id); } }else if(id.equals("-tw")){ int a = Integer.getInteger(val, 0); if(0 != a){ thumbWidth = a; }else{ System.out.println("invalid value->" + id); } }else if(id.equals("-d") || id.equals("-D")){ int a = Integer.getInteger(val, 0); if(0 != a){ delay = a; }else{ System.out.println("invalid value->" + id); } } i++; }else{ if(null != filename){ System.out.println("invalid argument(too many)->" + id); } if(null == uri){ uri = id; }else{ filename = id; } } } } }