├── tags └── 0.9 │ └── html2image │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── gui │ │ └── ava │ │ └── html │ │ ├── image │ │ ├── generator │ │ │ └── HtmlImageGenerator.java │ │ └── util │ │ │ ├── FormatNameUtil.java │ │ │ └── SynchronousHTMLEditorKit.java │ │ └── link │ │ ├── LinkHarvester.java │ │ └── LinkInfo.java │ └── test │ └── java │ └── gui │ └── ava │ └── html │ └── image │ ├── generator │ └── HtmlImageGeneratorTest.java │ └── util │ └── FormatNameUtilTest.java ├── trunk └── html2image │ ├── pom.xml │ └── src │ ├── main │ └── java │ │ └── gui │ │ └── ava │ │ └── html │ │ ├── Html2Image.java │ │ ├── exception │ │ └── RenderException.java │ │ ├── imagemap │ │ ├── ElementBox.java │ │ ├── HtmlImageMap.java │ │ └── HtmlImageMapImpl.java │ │ ├── parser │ │ ├── DocumentHolder.java │ │ ├── HtmlParser.java │ │ ├── HtmlParserImpl.java │ │ └── ParseException.java │ │ ├── pdf │ │ ├── PdfRenderer.java │ │ └── PdfRendererImpl.java │ │ └── renderer │ │ ├── FormatNameUtil.java │ │ ├── ImageRenderer.java │ │ ├── ImageRendererImpl.java │ │ └── LayoutHolder.java │ └── test │ ├── java │ └── gui │ │ └── ava │ │ └── html │ │ ├── BaseTest.java │ │ ├── imagemap │ │ └── HtmlImageMapImplTest.java │ │ ├── parser │ │ └── HtmlParserImplTest.java │ │ ├── pdf │ │ └── PdfRendererImplTest.java │ │ └── renderer │ │ ├── FormatNameUtilTest.java │ │ └── ImageRendererImplTest.java │ └── resources │ ├── test1.html │ └── test2.xhtml └── wiki ├── Html2Image.wiki └── HtmlImageGenerator.wiki /tags/0.9/html2image/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | gui.ava 5 | html2image 6 | jar 7 | 1.0-SNAPSHOT 8 | html2image 9 | http://maven.apache.org 10 | 11 | 12 | 13 | junit 14 | junit 15 | 4.8.1 16 | test 17 | 18 | 19 | 20 | 21 | 22 | yoava 23 | AOL yoava 24 | http://yoava.artifactoryonline.com/yoava/libs-releases-local 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-compiler-plugin 34 | 35 | 1.6 36 | 1.6 37 | utf-8 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /tags/0.9/html2image/src/main/java/gui/ava/html/image/generator/HtmlImageGenerator.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.image.generator; 2 | 3 | import gui.ava.html.image.util.FormatNameUtil; 4 | import gui.ava.html.image.util.SynchronousHTMLEditorKit; 5 | import gui.ava.html.link.LinkHarvester; 6 | import gui.ava.html.link.LinkInfo; 7 | 8 | import javax.imageio.ImageIO; 9 | import javax.swing.*; 10 | import java.awt.*; 11 | import java.awt.image.BufferedImage; 12 | import java.beans.PropertyChangeEvent; 13 | import java.beans.PropertyChangeListener; 14 | import java.io.File; 15 | import java.io.FileWriter; 16 | import java.io.IOException; 17 | import java.net.URL; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | /** 22 | * @author Yoav Aharoni 23 | */ 24 | public class HtmlImageGenerator { 25 | private JEditorPane editorPane; 26 | static final Dimension DEFAULT_SIZE = new Dimension(800, 800); 27 | 28 | public HtmlImageGenerator() { 29 | editorPane = createJEditorPane(); 30 | } 31 | 32 | public ComponentOrientation getOrientation() { 33 | return editorPane.getComponentOrientation(); 34 | } 35 | 36 | public void setOrientation(ComponentOrientation orientation) { 37 | editorPane.setComponentOrientation(orientation); 38 | } 39 | 40 | public Dimension getSize() { 41 | return editorPane.getSize(); 42 | } 43 | 44 | public void setSize(Dimension dimension) { 45 | editorPane.setSize(dimension); 46 | } 47 | 48 | public void loadUrl(URL url) { 49 | try { 50 | editorPane.setPage(url); 51 | } catch (IOException e) { 52 | throw new RuntimeException(String.format("Exception while loading %s", url), e); 53 | } 54 | } 55 | 56 | public void loadUrl(String url) { 57 | try { 58 | editorPane.setPage(url); 59 | } catch (IOException e) { 60 | throw new RuntimeException(String.format("Exception while loading %s", url), e); 61 | } 62 | } 63 | 64 | public void loadHtml(String html) { 65 | editorPane.setText(html); 66 | onDocumentLoad(); 67 | } 68 | 69 | public String getLinksMapMarkup(String mapName) { 70 | final StringBuilder markup = new StringBuilder(); 71 | markup.append("\n"); 72 | for (LinkInfo link : getLinks()) { 73 | final List bounds = link.getBounds(); 74 | for (Rectangle bound : bounds) { 75 | final int x1 = (int) bound.getX(); 76 | final int y1 = (int) bound.getY(); 77 | final int x2 = (int) (x1 + bound.getWidth()); 78 | final int y2 = (int) (y1 + bound.getHeight()); 79 | markup.append(String.format(" entry : link.getAttributes().entrySet()) { 81 | String attName = entry.getKey(); 82 | String value = entry.getValue(); 83 | markup.append(" ").append(attName).append("=\"").append(value.replace("\"", """)).append("\""); 84 | } 85 | markup.append(">\n"); 86 | } 87 | } 88 | markup.append("\n"); 89 | return markup.toString(); 90 | } 91 | 92 | public List getLinks() { 93 | final LinkHarvester harvester = new LinkHarvester(editorPane); 94 | return harvester.getLinks(); 95 | } 96 | 97 | public void saveAsHtmlWithMap(String file, String imageUrl) { 98 | saveAsHtmlWithMap(new File(file), imageUrl); 99 | } 100 | 101 | public void saveAsHtmlWithMap(File file, String imageUrl) { 102 | FileWriter writer = null; 103 | try { 104 | writer = new FileWriter(file); 105 | writer.append("\n"); 106 | writer.append("\n\n"); 107 | writer.append("\n"); 108 | final String htmlMap = getLinksMapMarkup("map"); 109 | writer.write(htmlMap); 110 | writer.append("\n"); 113 | writer.append("\n"); 114 | } catch (IOException e) { 115 | throw new RuntimeException(String.format("Exception while saving '%s' html file", file), e); 116 | } finally { 117 | if (writer != null) { 118 | try { 119 | writer.close(); 120 | } catch (IOException ignore) { 121 | } 122 | } 123 | } 124 | 125 | } 126 | 127 | public void saveAsImage(String file) { 128 | saveAsImage(new File(file)); 129 | } 130 | 131 | public void saveAsImage(File file) { 132 | 133 | BufferedImage img = getBufferedImage(); 134 | try { 135 | final String formatName = FormatNameUtil.formatForFilename(file.getName()); 136 | ImageIO.write(img, formatName, file); 137 | } catch (IOException e) { 138 | throw new RuntimeException(String.format("Exception while saving '%s' image", file), e); 139 | } 140 | } 141 | 142 | protected void onDocumentLoad() { 143 | } 144 | 145 | public Dimension getDefaultSize() { 146 | return DEFAULT_SIZE; 147 | } 148 | 149 | public BufferedImage getBufferedImage() { 150 | Dimension prefSize = editorPane.getPreferredSize(); 151 | BufferedImage img = new BufferedImage(prefSize.width, editorPane.getPreferredSize().height, BufferedImage.TYPE_INT_ARGB); 152 | Graphics graphics = img.getGraphics(); 153 | editorPane.setSize(prefSize); 154 | editorPane.paint(graphics); 155 | return img; 156 | } 157 | 158 | protected JEditorPane createJEditorPane() { 159 | final JEditorPane editorPane = new JEditorPane(); 160 | editorPane.setSize(getDefaultSize()); 161 | editorPane.setEditable(false); 162 | final SynchronousHTMLEditorKit kit = new SynchronousHTMLEditorKit(); 163 | editorPane.setEditorKitForContentType("text/html", kit); 164 | editorPane.setContentType("text/html"); 165 | editorPane.addPropertyChangeListener(new PropertyChangeListener() { 166 | public void propertyChange(PropertyChangeEvent evt) { 167 | if (evt.getPropertyName().equals("page")) { 168 | onDocumentLoad(); 169 | } 170 | } 171 | }); 172 | return editorPane; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /tags/0.9/html2image/src/main/java/gui/ava/html/image/util/FormatNameUtil.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.image.util; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author Yoav Aharoni 8 | */ 9 | public class FormatNameUtil { 10 | public static Map types = new HashMap(); 11 | private static final String DEFAULT_FORMAT = "png"; 12 | 13 | static { 14 | types.put("gif", "gif"); 15 | types.put("jpg", "jpg"); 16 | types.put("jpeg", "jpg"); 17 | types.put("png", "png"); 18 | } 19 | 20 | public static String formatForExtension(String extension) { 21 | final String type = types.get(extension); 22 | if (type == null) { 23 | return DEFAULT_FORMAT; 24 | } 25 | return type; 26 | } 27 | 28 | public static String formatForFilename(String fileName) { 29 | final int dotIndex = fileName.lastIndexOf('.'); 30 | if (dotIndex < 0) { 31 | return DEFAULT_FORMAT; 32 | } 33 | final String ext = fileName.substring(dotIndex + 1); 34 | return formatForExtension(ext); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tags/0.9/html2image/src/main/java/gui/ava/html/image/util/SynchronousHTMLEditorKit.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.image.util; 2 | 3 | import javax.swing.text.Document; 4 | import javax.swing.text.Element; 5 | import javax.swing.text.View; 6 | import javax.swing.text.ViewFactory; 7 | import javax.swing.text.html.HTMLDocument; 8 | import javax.swing.text.html.HTMLEditorKit; 9 | import javax.swing.text.html.ImageView; 10 | 11 | /** 12 | * @author Yoav Aharoni 13 | */ 14 | public class SynchronousHTMLEditorKit extends HTMLEditorKit { 15 | 16 | public Document createDefaultDocument() { 17 | HTMLDocument doc = (HTMLDocument) super.createDefaultDocument(); 18 | doc.setAsynchronousLoadPriority(-1); 19 | return doc; 20 | } 21 | 22 | public ViewFactory getViewFactory() { 23 | return new HTMLFactory() { 24 | public View create(Element elem) { 25 | View view = super.create(elem); 26 | if (view instanceof ImageView) { 27 | ((ImageView) view).setLoadsSynchronously(true); 28 | } 29 | return view; 30 | } 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tags/0.9/html2image/src/main/java/gui/ava/html/link/LinkHarvester.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.link; 2 | 3 | import javax.swing.*; 4 | import javax.swing.text.*; 5 | import javax.swing.text.html.HTML; 6 | import java.awt.*; 7 | import java.util.*; 8 | import java.util.List; 9 | 10 | /** 11 | * @author Yoav Aharoni 12 | */ 13 | public class LinkHarvester { 14 | private final JTextComponent textComponent; 15 | private final List links = new ArrayList(); 16 | 17 | public LinkHarvester(JEditorPane textComponent) { 18 | this.textComponent = textComponent; 19 | harvestElement(textComponent.getDocument().getDefaultRootElement()); 20 | } 21 | 22 | public List getLinks() { 23 | return links; 24 | } 25 | 26 | private void harvestElement(Element element) { 27 | if (element == null) { 28 | return; 29 | } 30 | 31 | final AttributeSet attributes = element.getAttributes(); 32 | final Enumeration attributeNames = attributes.getAttributeNames(); 33 | while (attributeNames.hasMoreElements()) { 34 | final Object key = attributeNames.nextElement(); 35 | if (HTML.Tag.A.equals(key)) { 36 | final Map linkAttributes = harvestAttributes(element); 37 | final List bounds = harvestBounds(element); 38 | if (!linkAttributes.isEmpty() && !bounds.isEmpty()) { 39 | links.add(new LinkInfo(linkAttributes, bounds)); 40 | } 41 | } 42 | } 43 | 44 | for (int i = 0; i < element.getElementCount(); i++) { 45 | final Element child = element.getElement(i); 46 | harvestElement(child); 47 | } 48 | } 49 | 50 | private Map harvestAttributes(Element element) { 51 | final Object value = element.getAttributes().getAttribute(HTML.Tag.A); 52 | if (value instanceof SimpleAttributeSet) { 53 | final SimpleAttributeSet attributeSet = (SimpleAttributeSet) value; 54 | final Map result = new HashMap(); 55 | addAttribute(attributeSet, result, HTML.Attribute.HREF); 56 | addAttribute(attributeSet, result, HTML.Attribute.TARGET); 57 | addAttribute(attributeSet, result, HTML.Attribute.TITLE); 58 | addAttribute(attributeSet, result, HTML.Attribute.CLASS); 59 | addAttribute(attributeSet, result, "tabindex"); 60 | addAttribute(attributeSet, result, "dir"); 61 | addAttribute(attributeSet, result, "lang"); 62 | addAttribute(attributeSet, result, "accesskey"); 63 | 64 | addAttribute(attributeSet, result, "onblur"); 65 | addAttribute(attributeSet, result, "onclick"); 66 | addAttribute(attributeSet, result, "ondblclick"); 67 | addAttribute(attributeSet, result, "onfocus"); 68 | addAttribute(attributeSet, result, "onmousedown"); 69 | addAttribute(attributeSet, result, "onmousemove"); 70 | addAttribute(attributeSet, result, "onmouseout"); 71 | addAttribute(attributeSet, result, "onmouseover"); 72 | addAttribute(attributeSet, result, "onmouseup"); 73 | addAttribute(attributeSet, result, "onkeydown"); 74 | addAttribute(attributeSet, result, "onkeypress"); 75 | addAttribute(attributeSet, result, "onkeyup"); 76 | return result; 77 | } 78 | 79 | return Collections.emptyMap(); 80 | } 81 | 82 | private void addAttribute(SimpleAttributeSet attributeSet, Map result, Object attribute) { 83 | final String attName = attribute.toString(); 84 | final String attValue = (String) attributeSet.getAttribute(attribute); 85 | if (attValue != null && !attValue.equals("")) { 86 | result.put(attName, attValue); 87 | } 88 | } 89 | 90 | private List harvestBounds(Element element) { 91 | final List boundsList = new ArrayList(); 92 | try { 93 | final int startOffset = element.getStartOffset(); 94 | final int endOffset = element.getEndOffset(); 95 | 96 | Rectangle lastBounds = null; 97 | for (int i = startOffset; i <= endOffset; i++) { 98 | final Rectangle bounds = textComponent.modelToView(i); 99 | // skip null rectangle 100 | if (bounds == null) { 101 | continue; 102 | } 103 | 104 | // set lastBounds 105 | if (lastBounds == null) { 106 | lastBounds = bounds; 107 | continue; 108 | } 109 | 110 | // union horizontal bounds 111 | if (bounds.getY() == lastBounds.getY()) { 112 | lastBounds = lastBounds.union(bounds); 113 | continue; 114 | } 115 | 116 | // add lastBounds to list 117 | if (lastBounds.getWidth() > 1 && lastBounds.getHeight() > 1) { 118 | boundsList.add(lastBounds); 119 | } 120 | lastBounds = null; 121 | } 122 | 123 | // add lastBounds to list 124 | if (lastBounds != null && lastBounds.getWidth() > 1 && lastBounds.getHeight() > 1) { 125 | boundsList.add(lastBounds); 126 | } 127 | return boundsList; 128 | 129 | } catch (BadLocationException e) { 130 | throw new RuntimeException("Got BadLocationException", e); 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /tags/0.9/html2image/src/main/java/gui/ava/html/link/LinkInfo.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.link; 2 | 3 | import java.awt.*; 4 | import java.util.List; 5 | import java.util.Map; 6 | 7 | /** 8 | * @author Yoav Aharoni 9 | */ 10 | public class LinkInfo { 11 | private Map attributes; 12 | private List bounds; 13 | 14 | public LinkInfo(Map attributes, List bounds) { 15 | this.attributes = attributes; 16 | this.bounds = bounds; 17 | } 18 | 19 | public Map getAttributes() { 20 | return attributes; 21 | } 22 | 23 | public List getBounds() { 24 | return bounds; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tags/0.9/html2image/src/test/java/gui/ava/html/image/generator/HtmlImageGeneratorTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.image.generator; 2 | 3 | import java.awt.*; 4 | 5 | 6 | public class HtmlImageGeneratorTest { 7 | // @Test 8 | public void testLoadUrl() { 9 | final HtmlImageGenerator imageGenerator = new HtmlImageGenerator(); 10 | imageGenerator.setOrientation(ComponentOrientation.RIGHT_TO_LEFT); 11 | imageGenerator.loadUrl("file:///D:/Temp/template.html"); 12 | imageGenerator.saveAsImage("d:/temp/test1.png"); 13 | imageGenerator.saveAsHtmlWithMap("/temp/test1.html", "test1.png"); 14 | } 15 | 16 | // @Test 17 | public void testLoadHtml() { 18 | final HtmlImageGenerator imageGenerator = new HtmlImageGenerator(); 19 | imageGenerator.loadHtml("

test test test xxx link
link
xxx xxx

\"ביטוח
\"ביטוח"); 20 | imageGenerator.saveAsImage("d:/temp/test2.png"); 21 | imageGenerator.saveAsHtmlWithMap("/temp/test2.html", "test2.png"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tags/0.9/html2image/src/test/java/gui/ava/html/image/util/FormatNameUtilTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.image.util; 2 | 3 | import gui.ava.html.image.util.FormatNameUtil; 4 | import org.junit.Assert; 5 | import org.junit.Test; 6 | 7 | /** 8 | * @author Yoav Aharoni 9 | */ 10 | public class FormatNameUtilTest { 11 | @Test 12 | public void testGif() { 13 | final String format = FormatNameUtil.formatForFilename("test.file.gif"); 14 | Assert.assertEquals("gif", format); 15 | } 16 | 17 | @Test 18 | public void testPng() { 19 | final String format = FormatNameUtil.formatForFilename("test.file.png"); 20 | Assert.assertEquals("png", format); 21 | } 22 | 23 | @Test 24 | public void testJpg() { 25 | final String format = FormatNameUtil.formatForFilename("test.file.jpg"); 26 | Assert.assertEquals("jpg", format); 27 | } 28 | 29 | @Test 30 | public void testNoName() { 31 | final String format = FormatNameUtil.formatForFilename(".gif"); 32 | Assert.assertEquals("gif", format); 33 | } 34 | 35 | @Test 36 | public void testNoExt() { 37 | final String format = FormatNameUtil.formatForFilename("name."); 38 | Assert.assertEquals("png", format); 39 | } 40 | 41 | @Test 42 | public void testEmptyFilename() { 43 | final String format = FormatNameUtil.formatForFilename(""); 44 | Assert.assertEquals("png", format); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /trunk/html2image/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | gui.ava 5 | html2image 6 | jar 7 | 2.0-SNAPSHOT 8 | html2image 9 | http://maven.apache.org 10 | 11 | 12 | 13 | org.xhtmlrenderer 14 | core-renderer 15 | R8 16 | 17 | 18 | net.sourceforge.nekohtml 19 | nekohtml 20 | 1.9.14 21 | 22 | 23 | commons-lang 24 | commons-lang 25 | 2.5 26 | 27 | 28 | junit 29 | junit 30 | 4.8.1 31 | test 32 | 33 | 34 | org.springframework 35 | org.springframework.core 36 | 3.0.3.RELEASE 37 | test 38 | 39 | 40 | 41 | 42 | 43 | jfrog-third-party-releases-local 44 | 45 | 46 | http://repo.jfrog.org/artifactory/third-party-releases-local 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.apache.maven.plugins 54 | maven-compiler-plugin 55 | 56 | 1.6 57 | 1.6 58 | utf-8 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/Html2Image.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html; 2 | 3 | import gui.ava.html.imagemap.HtmlImageMap; 4 | import gui.ava.html.imagemap.HtmlImageMapImpl; 5 | import gui.ava.html.parser.HtmlParser; 6 | import gui.ava.html.parser.HtmlParserImpl; 7 | import gui.ava.html.pdf.PdfRenderer; 8 | import gui.ava.html.pdf.PdfRendererImpl; 9 | import gui.ava.html.renderer.ImageRenderer; 10 | import gui.ava.html.renderer.ImageRendererImpl; 11 | import org.w3c.dom.Document; 12 | 13 | import java.io.File; 14 | import java.io.InputStream; 15 | import java.io.Reader; 16 | import java.net.URI; 17 | import java.net.URL; 18 | 19 | /** 20 | * @author Yoav Aharoni 21 | */ 22 | public class Html2Image { 23 | private HtmlParser parser = new HtmlParserImpl(); 24 | private HtmlImageMap htmlImageMap; 25 | private ImageRenderer imageRenderer; 26 | private PdfRenderer pdfRenderer; 27 | 28 | public HtmlParser getParser() { 29 | return parser; 30 | } 31 | 32 | public HtmlImageMap getHtmlImageMap() { 33 | if (htmlImageMap == null) { 34 | htmlImageMap = new HtmlImageMapImpl(getImageRenderer()); 35 | } 36 | return htmlImageMap; 37 | } 38 | 39 | public PdfRenderer getPdfRenderer() { 40 | if (pdfRenderer == null) { 41 | pdfRenderer = new PdfRendererImpl(parser); 42 | } 43 | return pdfRenderer; 44 | } 45 | 46 | public ImageRenderer getImageRenderer() { 47 | if (imageRenderer == null) { 48 | imageRenderer = new ImageRendererImpl(parser); 49 | } 50 | return imageRenderer; 51 | } 52 | 53 | public static Html2Image fromDocument(Document document) { 54 | final Html2Image html2Image = new Html2Image(); 55 | html2Image.getParser().setDocument(document); 56 | return html2Image; 57 | } 58 | 59 | public static Html2Image fromHtml(String html) { 60 | final Html2Image html2Image = new Html2Image(); 61 | html2Image.getParser().loadHtml(html); 62 | return html2Image; 63 | } 64 | 65 | public static Html2Image fromURL(URL url) { 66 | final Html2Image html2Image = new Html2Image(); 67 | html2Image.getParser().load(url); 68 | return html2Image; 69 | } 70 | 71 | public static Html2Image fromURI(URI uri) { 72 | final Html2Image html2Image = new Html2Image(); 73 | html2Image.getParser().load(uri); 74 | return html2Image; 75 | } 76 | 77 | public static Html2Image fromFile(File file) { 78 | final Html2Image html2Image = new Html2Image(); 79 | html2Image.getParser().load(file); 80 | return html2Image; 81 | } 82 | 83 | public static Html2Image fromReader(Reader reader) { 84 | final Html2Image html2Image = new Html2Image(); 85 | html2Image.getParser().load(reader); 86 | return html2Image; 87 | } 88 | 89 | public static Html2Image fromInputStream(InputStream inputStream) { 90 | final Html2Image html2Image = new Html2Image(); 91 | html2Image.getParser().load(inputStream); 92 | return html2Image; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/exception/RenderException.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.exception; 2 | 3 | /** 4 | * @author Yoav Aharoni 5 | */ 6 | public class RenderException extends RuntimeException { 7 | public RenderException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/imagemap/ElementBox.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.imagemap; 2 | 3 | import org.w3c.dom.Element; 4 | 5 | import java.util.Collection; 6 | 7 | /** 8 | * @author Yoav Aharoni 9 | */ 10 | public class ElementBox { 11 | private Element element; 12 | private int left; 13 | private int top; 14 | private int width; 15 | private int height; 16 | 17 | public ElementBox(Element element, int left, int top, int width, int height) { 18 | this.element = element; 19 | this.left = left; 20 | this.top = top; 21 | this.width = width; 22 | this.height = height; 23 | } 24 | 25 | public Element getElement() { 26 | return element; 27 | } 28 | 29 | public int getLeft() { 30 | return left; 31 | } 32 | 33 | public int getTop() { 34 | return top; 35 | } 36 | 37 | public int getWidth() { 38 | return width; 39 | } 40 | 41 | public int getHeight() { 42 | return height; 43 | } 44 | 45 | public int getRight() { 46 | return left + width; 47 | } 48 | 49 | public int getBottom() { 50 | return top + height; 51 | } 52 | 53 | public boolean isEmpty() { 54 | return width <= 0 || height <= 0; 55 | } 56 | 57 | public boolean containedIn(Collection elementBoxes) { 58 | for (ElementBox box : elementBoxes) { 59 | if (containedIn(box)) { 60 | return true; 61 | } 62 | } 63 | return false; 64 | } 65 | 66 | public boolean containedIn(ElementBox box) { 67 | return getTop() >= box.getTop() && getLeft() >= box.getTop() 68 | && getBottom() <= box.getBottom() && getRight() <= box.getRight(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/imagemap/HtmlImageMap.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.imagemap; 2 | 3 | import org.w3c.dom.Element; 4 | 5 | import java.io.File; 6 | import java.io.Writer; 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | /** 11 | * @author Yoav Aharoni 12 | */ 13 | public interface HtmlImageMap { 14 | Map> getClickableBoxes(); 15 | 16 | String getImageMap(String mapName, String imageURL); 17 | 18 | void saveImageMap(Writer writer, String mapName, String imageURL); 19 | 20 | String getImageMapDocument(String imageURL); 21 | 22 | void saveImageMapDocument(String filename, String imageURL); 23 | 24 | void saveImageMapDocument(File file, String imageURL); 25 | 26 | void saveImageMapDocument(Writer writer, String imageURL, boolean closeWriter); 27 | } 28 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/imagemap/HtmlImageMapImpl.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.imagemap; 2 | 3 | import gui.ava.html.exception.RenderException; 4 | import gui.ava.html.renderer.LayoutHolder; 5 | import org.apache.commons.lang.StringUtils; 6 | import org.w3c.dom.Element; 7 | import org.w3c.dom.NamedNodeMap; 8 | import org.w3c.dom.Node; 9 | import org.xhtmlrenderer.layout.Styleable; 10 | import org.xhtmlrenderer.render.BlockBox; 11 | import org.xhtmlrenderer.render.Box; 12 | import org.xhtmlrenderer.render.InlineLayoutBox; 13 | import org.xhtmlrenderer.render.LineBox; 14 | 15 | import java.io.*; 16 | import java.util.*; 17 | 18 | import static java.lang.String.format; 19 | 20 | /** 21 | * @author Yoav Aharoni 22 | */ 23 | public class HtmlImageMapImpl implements HtmlImageMap { 24 | private static Set searchedAttributes = stringSet("href", "onclick", "ondblclick", "onmousedown", "onmouseup"); 25 | private static Set allowedAttributes = stringSet( 26 | "href", "target", "title", "class", "tabindex", "dir", "lang", "accesskey", 27 | "onblur", "onclick", "ondblclick", "onfocus", 28 | "onmousedown", "onmousemove", "onmouseout", "onmouseover", "onmouseup", 29 | "onkeydown", "onkeypress", "onkeyup"); 30 | 31 | private LayoutHolder layoutHolder; 32 | 33 | public HtmlImageMapImpl(LayoutHolder layoutHolder) { 34 | this.layoutHolder = layoutHolder; 35 | } 36 | 37 | @Override 38 | public String getImageMap(String mapName, String imageURL) { 39 | final StringWriter writer = new StringWriter(); 40 | saveImageMap(writer, mapName, imageURL); 41 | return writer.toString(); 42 | } 43 | 44 | @Override 45 | public void saveImageMap(Writer writer, String mapName, String imageURL) { 46 | try { 47 | writer.append("\n"); 48 | for (Collection boxes : getClickableBoxes().values()) { 49 | for (ElementBox elementBox : boxes) { 50 | final int x1 = elementBox.getLeft(); 51 | final int y1 = elementBox.getTop(); 52 | final int x2 = elementBox.getRight(); 53 | final int y2 = elementBox.getBottom(); 54 | writer.append(format("\n"); 68 | } 69 | } 70 | writer.append("\n"); 71 | } catch (IOException e) { 72 | throw new RenderException("IOException while writing client-side image map.", e); 73 | } 74 | } 75 | 76 | @Override 77 | public String getImageMapDocument(String imageURL) { 78 | final StringWriter writer = new StringWriter(); 79 | saveImageMapDocument(writer, imageURL, true); 80 | return writer.toString(); 81 | } 82 | 83 | @Override 84 | public void saveImageMapDocument(Writer writer, String imageURL, boolean closeWriter) { 85 | try { 86 | writer.append("\n"); 87 | writer.append("\n\n"); 88 | writer.append("\n"); 89 | saveImageMap(writer, "map", imageURL); 90 | writer.append("\n"); 93 | writer.append("\n"); 94 | } catch (IOException e) { 95 | throw new RenderException("IOException while writing image map document.", e); 96 | } finally { 97 | if (closeWriter) { 98 | try { 99 | writer.close(); 100 | } catch (IOException ignore) { 101 | } 102 | } 103 | } 104 | } 105 | 106 | @Override 107 | public void saveImageMapDocument(File file, String imageURL) { 108 | try { 109 | saveImageMapDocument(new FileWriter(file), imageURL, true); 110 | } catch (IOException e) { 111 | throw new RenderException(format("IOException while writing image map document '%s'.", file.getAbsolutePath()), e); 112 | } 113 | } 114 | 115 | @Override 116 | public void saveImageMapDocument(String filename, String imageURL) { 117 | saveImageMapDocument(new File(filename), imageURL); 118 | } 119 | 120 | @Override 121 | public Map> getClickableBoxes() { 122 | final Box rootBox = layoutHolder.getRootBox(); 123 | final HashMap> boxes = new HashMap>(); 124 | addClickableElements(rootBox, boxes, new HashSet()); 125 | return boxes; 126 | } 127 | 128 | @SuppressWarnings({"unchecked"}) 129 | private void addClickableElements(Styleable styleable, HashMap> boxes, Set visited) { 130 | if (styleable == null || visited.contains(styleable)) { 131 | return; 132 | } 133 | visited.add(styleable); 134 | 135 | addIfClickable(styleable, boxes); 136 | 137 | if (styleable instanceof Box) { 138 | for (Styleable child : (List) ((Box) styleable).getChildren()) { 139 | addClickableElements(child, boxes, visited); 140 | } 141 | } 142 | if (styleable instanceof InlineLayoutBox) { 143 | for (Object child : (List) ((InlineLayoutBox) styleable).getInlineChildren()) { 144 | if (child instanceof Styleable) { 145 | addClickableElements((Styleable) child, boxes, visited); 146 | } 147 | } 148 | } else if (styleable instanceof BlockBox) { 149 | final List content = (List) ((BlockBox) styleable).getInlineContent(); 150 | if (content != null) { 151 | for (Styleable child : content) { 152 | addClickableElements(child, boxes, visited); 153 | } 154 | } 155 | } else if (styleable instanceof LineBox) { 156 | for (Styleable child : (List) ((LineBox) styleable).getNonFlowContent()) { 157 | addClickableElements(child, boxes, visited); 158 | } 159 | } 160 | } 161 | 162 | private void addIfClickable(Styleable styleable, HashMap> boxes) { 163 | final Element clickable = getClickableElement(styleable); 164 | if (clickable == null) { 165 | return; 166 | } 167 | final ElementBox elementBox = createElementBox(styleable, clickable); 168 | if (elementBox == null || elementBox.isEmpty()) { 169 | return; 170 | } 171 | Collection elementBoxes = boxes.get(clickable); 172 | if (elementBoxes == null) { 173 | elementBoxes = new ArrayList(); 174 | boxes.put(clickable, elementBoxes); 175 | elementBoxes.add(elementBox); 176 | return; 177 | } 178 | if (!elementBox.containedIn(elementBoxes)) { 179 | elementBoxes.add(elementBox); 180 | } 181 | } 182 | 183 | private ElementBox createElementBox(Styleable styleable, Element element) { 184 | if (styleable instanceof InlineLayoutBox) { 185 | final InlineLayoutBox box = (InlineLayoutBox) styleable; 186 | final int width = Math.max(box.getInlineWidth(), box.getWidth()); 187 | return new ElementBox(element, box.getAbsX(), box.getAbsY(), width, box.getHeight()); 188 | } 189 | if (styleable instanceof Box) { 190 | final Box box = (Box) styleable; 191 | return new ElementBox(element, box.getAbsX(), box.getAbsY(), box.getWidth(), box.getHeight()); 192 | } 193 | return null; 194 | } 195 | 196 | private Element getClickableElement(Styleable box) { 197 | Element element = box.getElement(); 198 | while (element != null) { 199 | if (isClickable(element)) { 200 | return element; 201 | } 202 | final Node parentNode = element.getParentNode(); 203 | element = parentNode instanceof Element ? (Element) parentNode : null; 204 | } 205 | return null; 206 | } 207 | 208 | private boolean isClickable(Element element) { 209 | for (String attribute : searchedAttributes) { 210 | final String value = element.getAttribute(attribute); 211 | if (StringUtils.isNotBlank(value)) { 212 | return true; 213 | } 214 | } 215 | return false; 216 | } 217 | 218 | private static HashSet stringSet(String... items) { 219 | return new HashSet(Arrays.asList(items)); 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/parser/DocumentHolder.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.parser; 2 | 3 | import org.w3c.dom.Document; 4 | 5 | /** 6 | * @author Yoav Aharoni 7 | */ 8 | public interface DocumentHolder { 9 | Document getDocument(); 10 | } 11 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/parser/HtmlParser.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.parser; 2 | 3 | import org.apache.xerces.parsers.DOMParser; 4 | import org.w3c.dom.Document; 5 | 6 | import java.io.File; 7 | import java.io.InputStream; 8 | import java.io.Reader; 9 | import java.net.URI; 10 | import java.net.URL; 11 | 12 | /** 13 | * @author Yoav Aharoni 14 | */ 15 | public interface HtmlParser extends DocumentHolder { 16 | 17 | DOMParser getDomParser(); 18 | 19 | void setDomParser(DOMParser domParser); 20 | 21 | void setDocument(Document document); 22 | 23 | void load(URL url); 24 | 25 | void load(URI uri); 26 | 27 | void load(File file); 28 | 29 | void load(Reader reader); 30 | 31 | void load(InputStream inputStream); 32 | 33 | void loadHtml(String html); 34 | 35 | void loadURI(String uri); 36 | } 37 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/parser/HtmlParserImpl.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.parser; 2 | 3 | import org.apache.xerces.parsers.DOMParser; 4 | import org.cyberneko.html.HTMLConfiguration; 5 | import org.w3c.dom.Document; 6 | import org.xml.sax.InputSource; 7 | import org.xml.sax.SAXException; 8 | import org.xml.sax.SAXNotRecognizedException; 9 | import org.xml.sax.SAXNotSupportedException; 10 | 11 | import java.io.*; 12 | import java.net.URI; 13 | import java.net.URL; 14 | 15 | import static java.lang.String.format; 16 | 17 | /** 18 | * @author Yoav Aharoni 19 | */ 20 | public class HtmlParserImpl implements HtmlParser { 21 | private DOMParser domParser; 22 | private Document document; 23 | 24 | public HtmlParserImpl() { 25 | domParser = new DOMParser(new HTMLConfiguration()); 26 | try { 27 | domParser.setProperty("http://cyberneko.org/html/properties/names/elems", "lower"); 28 | } catch (SAXNotRecognizedException e) { 29 | throw new ParseException("Can't create HtmlParserImpl", e); 30 | } catch (SAXNotSupportedException e) { 31 | throw new ParseException("Can't create HtmlParserImpl", e); 32 | } 33 | } 34 | 35 | @Override 36 | public DOMParser getDomParser() { 37 | return domParser; 38 | } 39 | 40 | @Override 41 | public void setDomParser(DOMParser domParser) { 42 | this.domParser = domParser; 43 | } 44 | 45 | @Override 46 | public Document getDocument() { 47 | return document; 48 | } 49 | 50 | @Override 51 | public void setDocument(Document document) { 52 | this.document = document; 53 | } 54 | 55 | @Override 56 | public void load(Reader reader) { 57 | try { 58 | domParser.parse(new InputSource(reader)); 59 | document = domParser.getDocument(); 60 | } catch (SAXException e) { 61 | throw new ParseException("SAXException while parsing HTML.", e); 62 | } catch (IOException e) { 63 | throw new ParseException("IOException while parsing HTML.", e); 64 | } finally { 65 | try { 66 | reader.close(); 67 | } catch (IOException ignore) { 68 | } 69 | } 70 | } 71 | 72 | @Override 73 | public void load(InputStream inputStream) { 74 | try { 75 | domParser.parse(new InputSource(inputStream)); 76 | document = domParser.getDocument(); 77 | } catch (SAXException e) { 78 | throw new ParseException("SAXException while parsing HTML.", e); 79 | } catch (IOException e) { 80 | throw new ParseException("IOException while parsing HTML.", e); 81 | } 82 | finally { 83 | try { 84 | inputStream.close(); 85 | } catch (IOException ignore) { 86 | } 87 | } 88 | } 89 | 90 | @Override 91 | public void loadURI(String uri) { 92 | try { 93 | domParser.parse(new InputSource(uri)); 94 | document = domParser.getDocument(); 95 | } catch (SAXException e) { 96 | throw new ParseException(format("SAXException while parsing HTML from \"%s\".", uri), e); 97 | } catch (IOException e) { 98 | throw new ParseException(format("SAXException while parsing HTML from \"%s\".", uri), e); 99 | } 100 | } 101 | 102 | @Override 103 | public void load(File file) { 104 | load(file.toURI()); 105 | } 106 | 107 | @Override 108 | public void load(URL url) { 109 | loadURI(url.toExternalForm()); 110 | } 111 | 112 | @Override 113 | public void load(URI uri) { 114 | loadURI(uri.toString()); 115 | } 116 | 117 | @Override 118 | public void loadHtml(String html) { 119 | load(new StringReader(html)); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/parser/ParseException.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.parser; 2 | 3 | /** 4 | * @author Yoav Aharoni 5 | */ 6 | public class ParseException extends RuntimeException { 7 | public ParseException(String message, Throwable cause) { 8 | super(message, cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/pdf/PdfRenderer.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.pdf; 2 | 3 | import java.io.File; 4 | import java.io.OutputStream; 5 | 6 | /** 7 | * @author Yoav Aharoni 8 | */ 9 | public interface PdfRenderer { 10 | void saveToPDF(OutputStream outputStream, boolean closeStream); 11 | 12 | void saveToPDF(File file); 13 | 14 | void saveToPDF(String file); 15 | } 16 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/pdf/PdfRendererImpl.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.pdf; 2 | 3 | import com.lowagie.text.DocumentException; 4 | import gui.ava.html.exception.RenderException; 5 | import gui.ava.html.parser.DocumentHolder; 6 | import org.w3c.dom.Document; 7 | import org.xhtmlrenderer.pdf.ITextRenderer; 8 | 9 | import java.io.*; 10 | 11 | /** 12 | * @author Yoav Aharoni 13 | */ 14 | public class PdfRendererImpl implements PdfRenderer { 15 | private DocumentHolder documentHolder; 16 | 17 | public PdfRendererImpl(DocumentHolder documentHolder) { 18 | this.documentHolder = documentHolder; 19 | } 20 | 21 | @Override 22 | public void saveToPDF(OutputStream outputStream, boolean closeStream) { 23 | try { 24 | ITextRenderer renderer = new ITextRenderer(); 25 | final Document document = documentHolder.getDocument(); 26 | renderer.setDocument(document, document.getDocumentURI()); 27 | renderer.layout(); 28 | renderer.createPDF(outputStream); 29 | } catch (DocumentException e) { 30 | throw new RenderException("DocumentException while rendering PDF", e); 31 | } finally { 32 | if (closeStream) { 33 | try { 34 | outputStream.close(); 35 | } catch (IOException ignore) { 36 | } 37 | } 38 | } 39 | } 40 | 41 | @Override 42 | public void saveToPDF(File file) { 43 | try { 44 | saveToPDF(new FileOutputStream(file), true); 45 | } catch (FileNotFoundException e) { 46 | throw new RenderException(String.format("File not found %s", file.getAbsolutePath()), e); 47 | } 48 | } 49 | 50 | @Override 51 | public void saveToPDF(String file) { 52 | saveToPDF(new File(file)); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/renderer/FormatNameUtil.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.renderer; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author Yoav Aharoni 8 | */ 9 | public class FormatNameUtil { 10 | public static Map types = new HashMap(); 11 | private static final String DEFAULT_FORMAT = "png"; 12 | 13 | static { 14 | types.put("gif", "gif"); 15 | types.put("jpg", "jpg"); 16 | types.put("jpeg", "jpg"); 17 | types.put("png", "png"); 18 | types.put("bmp", "bmp"); 19 | } 20 | 21 | public static String formatForExtension(String extension) { 22 | final String type = types.get(extension); 23 | if (type == null) { 24 | return DEFAULT_FORMAT; 25 | } 26 | return type; 27 | } 28 | 29 | public static String getDefaultFormat() { 30 | return DEFAULT_FORMAT; 31 | } 32 | 33 | public static String formatForFilename(String fileName) { 34 | final int dotIndex = fileName.lastIndexOf('.'); 35 | if (dotIndex < 0) { 36 | return DEFAULT_FORMAT; 37 | } 38 | final String ext = fileName.substring(dotIndex + 1); 39 | return formatForExtension(ext); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/renderer/ImageRenderer.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.renderer; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.File; 5 | import java.io.OutputStream; 6 | 7 | /** 8 | * @author Yoav Aharoni 9 | */ 10 | public interface ImageRenderer extends LayoutHolder { 11 | int getWidth(); 12 | 13 | ImageRenderer setWidth(int width); 14 | 15 | int getHeight(); 16 | 17 | ImageRenderer setHeight(int height); 18 | 19 | boolean isAutoHeight(); 20 | 21 | ImageRenderer setAutoHeight(boolean autoHeight); 22 | 23 | String getImageFormat(); 24 | 25 | ImageRenderer setImageType(String imageType); 26 | 27 | BufferedImage getBufferedImage(int imageType); 28 | 29 | BufferedImage getBufferedImage(); 30 | 31 | void saveImage(OutputStream outputStream, boolean closeStream); 32 | 33 | void saveImage(String filename); 34 | 35 | void saveImage(File file); 36 | 37 | ImageRendererImpl clearCache(); 38 | 39 | float getWriteCompressionQuality(); 40 | 41 | ImageRenderer setWriteCompressionQuality(float writeCompressionQuality); 42 | 43 | int getWriteCompressionMode(); 44 | 45 | ImageRenderer setWriteCompressionMode(int writeCompressionMode); 46 | 47 | String getWriteCompressionType(); 48 | 49 | ImageRenderer setWriteCompressionType(String writeCompressionType); 50 | } 51 | -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/renderer/ImageRendererImpl.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.renderer; 2 | 3 | import gui.ava.html.exception.RenderException; 4 | import gui.ava.html.parser.DocumentHolder; 5 | import org.w3c.dom.Document; 6 | import org.xhtmlrenderer.render.Box; 7 | import org.xhtmlrenderer.simple.Graphics2DRenderer; 8 | import org.xhtmlrenderer.util.FSImageWriter; 9 | 10 | import javax.imageio.ImageWriteParam; 11 | import java.awt.*; 12 | import java.awt.image.BufferedImage; 13 | import java.io.*; 14 | 15 | /** 16 | * @author Yoav Aharoni 17 | */ 18 | public class ImageRendererImpl implements ImageRenderer { 19 | public static final int DEFAULT_WIDTH = 1024; 20 | public static final int DEFAULT_HEIGHT = 768; 21 | 22 | private DocumentHolder documentHolder; 23 | 24 | private int width = DEFAULT_WIDTH; 25 | private int height = DEFAULT_HEIGHT; 26 | private boolean autoHeight = true; 27 | 28 | private String imageFormat = null; 29 | private float writeCompressionQuality = 1.0f; 30 | private int writeCompressionMode = ImageWriteParam.MODE_COPY_FROM_METADATA; 31 | private String writeCompressionType = null; 32 | private Box rootBox; 33 | 34 | private BufferedImage bufferedImage; 35 | private int cacheImageType = -1; 36 | private Document cacheDocument; 37 | 38 | public ImageRendererImpl(DocumentHolder documentHolder) { 39 | this.documentHolder = documentHolder; 40 | } 41 | 42 | @Override 43 | public int getWidth() { 44 | return width; 45 | } 46 | 47 | @Override 48 | public ImageRenderer setWidth(int width) { 49 | this.width = width; 50 | return this; 51 | } 52 | 53 | @Override 54 | public int getHeight() { 55 | return height; 56 | } 57 | 58 | @Override 59 | public ImageRenderer setHeight(int height) { 60 | this.height = height; 61 | return this; 62 | } 63 | 64 | @Override 65 | public boolean isAutoHeight() { 66 | return autoHeight; 67 | } 68 | 69 | @Override 70 | public ImageRenderer setAutoHeight(boolean autoHeight) { 71 | this.autoHeight = autoHeight; 72 | return this; 73 | } 74 | 75 | public String getImageFormat() { 76 | return imageFormat; 77 | } 78 | 79 | public ImageRenderer setImageType(String imageType) { 80 | this.imageFormat = imageType; 81 | return this; 82 | } 83 | 84 | @Override 85 | public float getWriteCompressionQuality() { 86 | return writeCompressionQuality; 87 | } 88 | 89 | @Override 90 | public ImageRenderer setWriteCompressionQuality(float writeCompressionQuality) { 91 | this.writeCompressionQuality = writeCompressionQuality; 92 | return this; 93 | } 94 | 95 | @Override 96 | public int getWriteCompressionMode() { 97 | return writeCompressionMode; 98 | } 99 | 100 | @Override 101 | public ImageRenderer setWriteCompressionMode(int writeCompressionMode) { 102 | this.writeCompressionMode = writeCompressionMode; 103 | return this; 104 | } 105 | 106 | @Override 107 | public String getWriteCompressionType() { 108 | return writeCompressionType; 109 | } 110 | 111 | @Override 112 | public ImageRenderer setWriteCompressionType(String writeCompressionType) { 113 | this.writeCompressionType = writeCompressionType; 114 | return this; 115 | } 116 | 117 | @Override 118 | public BufferedImage getBufferedImage(int imageType) { 119 | final Document document = documentHolder.getDocument(); 120 | if (bufferedImage != null || cacheImageType != imageType || cacheDocument != document) { 121 | cacheImageType = imageType; 122 | cacheDocument = document; 123 | Graphics2DRenderer renderer = new Graphics2DRenderer(); 124 | renderer.setDocument(document, document.getDocumentURI()); 125 | Dimension dimension = new Dimension(width, height); 126 | bufferedImage = new BufferedImage(width, height, imageType); 127 | 128 | if (autoHeight) { 129 | // do layout with temp buffer 130 | Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics(); 131 | renderer.layout(graphics2D, new Dimension(width, height)); 132 | graphics2D.dispose(); 133 | 134 | Rectangle size = renderer.getMinimumSize(); 135 | final int autoWidth = (int) size.getWidth(); 136 | final int autoHeight = (int) size.getHeight(); 137 | bufferedImage = new BufferedImage(autoWidth, autoHeight, imageType); 138 | dimension = new Dimension(autoWidth, autoHeight); 139 | } 140 | 141 | Graphics2D graphics2D = (Graphics2D) bufferedImage.getGraphics(); 142 | renderer.layout(graphics2D, dimension); 143 | renderer.render(graphics2D); 144 | rootBox = renderer.getPanel().getRootBox(); 145 | graphics2D.dispose(); 146 | } 147 | return bufferedImage; 148 | } 149 | 150 | @Override 151 | public Box getRootBox() { 152 | if (rootBox == null) { 153 | getBufferedImage(); 154 | } 155 | return rootBox; 156 | } 157 | 158 | @Override 159 | public ImageRendererImpl clearCache() { 160 | bufferedImage = null; 161 | rootBox = null; 162 | cacheDocument = null; 163 | cacheImageType = -1; 164 | return this; 165 | } 166 | 167 | public BufferedImage getBufferedImage() { 168 | return getBufferedImage(BufferedImage.TYPE_INT_ARGB); 169 | } 170 | 171 | @Override 172 | public void saveImage(OutputStream outputStream, boolean closeStream) { 173 | save(outputStream, null, closeStream); 174 | } 175 | 176 | @Override 177 | public void saveImage(File file) { 178 | try { 179 | BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(file)); 180 | save(outputStream, file.getName(), true); 181 | } catch (IOException e) { 182 | throw new RenderException("IOException while rendering image to " + file.getAbsolutePath(), e); 183 | } 184 | } 185 | 186 | @Override 187 | public void saveImage(String filename) { 188 | saveImage(new File(filename)); 189 | } 190 | 191 | private void save(OutputStream outputStream, String filename, boolean closeStream) { 192 | try { 193 | final String imageFormat = getImageFormat(filename); 194 | final FSImageWriter imageWriter = getImageWriter(imageFormat); 195 | final boolean isBMP = "bmp".equalsIgnoreCase(imageFormat); 196 | final BufferedImage bufferedImage = getBufferedImage(isBMP ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB); 197 | imageWriter.write(bufferedImage, outputStream); 198 | } catch (IOException e) { 199 | throw new RenderException("IOException while rendering image", e); 200 | } finally { 201 | if (closeStream) { 202 | try { 203 | outputStream.close(); 204 | } catch (IOException ignore) { 205 | } 206 | } 207 | } 208 | } 209 | 210 | private FSImageWriter getImageWriter(String imageFormat) { 211 | FSImageWriter imageWriter = new FSImageWriter(imageFormat); 212 | imageWriter.setWriteCompressionMode(writeCompressionMode); 213 | imageWriter.setWriteCompressionQuality(writeCompressionQuality); 214 | imageWriter.setWriteCompressionType(writeCompressionType); 215 | return imageWriter; 216 | } 217 | 218 | private String getImageFormat(String filename) { 219 | if (this.imageFormat != null) { 220 | return imageFormat; 221 | } 222 | if (filename != null) { 223 | return FormatNameUtil.formatForFilename(filename); 224 | } 225 | return FormatNameUtil.getDefaultFormat(); 226 | } 227 | } -------------------------------------------------------------------------------- /trunk/html2image/src/main/java/gui/ava/html/renderer/LayoutHolder.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.renderer; 2 | 3 | import org.xhtmlrenderer.render.Box; 4 | 5 | /** 6 | * @author Yoav Aharoni 7 | */ 8 | public interface LayoutHolder { 9 | Box getRootBox(); 10 | } 11 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/java/gui/ava/html/BaseTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html; 2 | 3 | import org.springframework.util.ResourceUtils; 4 | 5 | import java.io.FileNotFoundException; 6 | import java.net.URL; 7 | 8 | /** 9 | * @author Yoav Aharoni 10 | */ 11 | public class BaseTest { 12 | public static final String TEST1_PATH = "classpath:test1.html"; 13 | 14 | public static URL getTest1Url() { 15 | try { 16 | return ResourceUtils.getURL(TEST1_PATH); 17 | } catch (FileNotFoundException e) { 18 | throw new RuntimeException(e); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/java/gui/ava/html/imagemap/HtmlImageMapImplTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.imagemap; 2 | 3 | import gui.ava.html.BaseTest; 4 | import gui.ava.html.Html2Image; 5 | import org.junit.Test; 6 | 7 | import java.net.URL; 8 | 9 | /** 10 | * @author Yoav Aharoni 11 | */ 12 | public class HtmlImageMapImplTest extends BaseTest { 13 | @Test 14 | public void test1ImageMapDocument() throws Exception { 15 | final Html2Image html2Image = Html2Image.fromURL(getTest1Url()); 16 | html2Image.getImageRenderer().saveImage("test1.png"); 17 | html2Image.getHtmlImageMap().saveImageMapDocument("test1.html", "test1.png"); 18 | } 19 | 20 | 21 | @Test 22 | public void googleImageMapDocument() throws Exception { 23 | final Html2Image html2Image = Html2Image.fromURL(new URL("http://www.google.com")); 24 | html2Image.getImageRenderer().saveImage("google.png"); 25 | html2Image.getHtmlImageMap().saveImageMapDocument("google.html", "google.png"); 26 | } 27 | 28 | @Test 29 | public void hebImageMapDocument() throws Exception { 30 | final Html2Image html2Image = Html2Image.fromHtml(""); 31 | html2Image.getImageRenderer().saveImage("heb.png"); 32 | html2Image.getHtmlImageMap().saveImageMapDocument("heb.html", "heb.png"); 33 | } 34 | 35 | @Test 36 | public void imageImageMapDocument() throws Exception { 37 | final Html2Image html2Image = Html2Image.fromHtml("
HELLO!
"); 38 | html2Image.getImageRenderer().saveImage("image.png"); 39 | html2Image.getHtmlImageMap().saveImageMapDocument("image.html", "heb.png"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/java/gui/ava/html/parser/HtmlParserImplTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.parser; 2 | 3 | import gui.ava.html.BaseTest; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | import org.springframework.util.ResourceUtils; 7 | import org.w3c.dom.Document; 8 | 9 | import java.io.FileInputStream; 10 | import java.io.FileReader; 11 | import java.net.URL; 12 | 13 | import static org.junit.Assert.assertEquals; 14 | import static org.junit.Assert.assertTrue; 15 | 16 | /** 17 | * @author Yoav Aharoni 18 | */ 19 | public class HtmlParserImplTest extends BaseTest { 20 | private HtmlParserImpl parser; 21 | 22 | @Before 23 | public void createParser() { 24 | parser = new HtmlParserImpl(); 25 | } 26 | 27 | @Test 28 | public void testLoadURI() throws Exception { 29 | parser.load(getTest1Url().toURI()); 30 | assertTest1(); 31 | } 32 | 33 | @Test 34 | public void testLoadExternalURL() throws Exception { 35 | parser.load(new URL("http://www.google.co.il")); 36 | assertTrue(getDocument().getElementsByTagName("div").getLength() > 0); 37 | } 38 | 39 | @Test 40 | public void testLoadFile() throws Exception { 41 | parser.load(ResourceUtils.getFile(TEST1_PATH)); 42 | assertTest1(); 43 | } 44 | 45 | @Test 46 | public void testLoadReader() throws Exception { 47 | parser.load(new FileReader(ResourceUtils.getFile(TEST1_PATH))); 48 | assertTest1(); 49 | } 50 | 51 | @Test 52 | public void testLoadInputStream() throws Exception { 53 | parser.load(new FileInputStream(ResourceUtils.getFile(TEST1_PATH))); 54 | assertTest1(); 55 | } 56 | 57 | @Test 58 | public void testLoadHtml() throws Exception { 59 | parser.loadHtml("Hello"); 60 | assertEquals(getDocument().getElementsByTagName("b").item(0).getTextContent(), "Hello"); 61 | } 62 | 63 | private void assertTest1() { 64 | assertEquals(getDocument().getElementsByTagName("strong").item(0).getTextContent(), "Hello"); 65 | } 66 | 67 | private Document getDocument() { 68 | return parser.getDocument(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/java/gui/ava/html/pdf/PdfRendererImplTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.pdf; 2 | 3 | import gui.ava.html.BaseTest; 4 | import gui.ava.html.Html2Image; 5 | import org.junit.Test; 6 | 7 | /** 8 | * @author Yoav Aharoni 9 | */ 10 | public class PdfRendererImplTest extends BaseTest { 11 | @Test 12 | public void testSaveToPDF() throws Exception { 13 | Html2Image.fromURL(getTest1Url()).getPdfRenderer().saveToPDF("test.pdf"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/java/gui/ava/html/renderer/FormatNameUtilTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.renderer; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | /** 7 | * @author Yoav Aharoni 8 | */ 9 | public class FormatNameUtilTest { 10 | @Test 11 | public void testGif() { 12 | final String format = FormatNameUtil.formatForFilename("test.file.gif"); 13 | Assert.assertEquals("gif", format); 14 | } 15 | 16 | @Test 17 | public void testPng() { 18 | final String format = FormatNameUtil.formatForFilename("test.file.png"); 19 | Assert.assertEquals("png", format); 20 | } 21 | 22 | @Test 23 | public void testJpg() { 24 | final String format = FormatNameUtil.formatForFilename("test.file.jpg"); 25 | Assert.assertEquals("jpg", format); 26 | } 27 | 28 | @Test 29 | public void testNoName() { 30 | final String format = FormatNameUtil.formatForFilename(".gif"); 31 | Assert.assertEquals("gif", format); 32 | } 33 | 34 | @Test 35 | public void testNoExtension() { 36 | final String format = FormatNameUtil.formatForFilename("name."); 37 | Assert.assertEquals("png", format); 38 | } 39 | 40 | @Test 41 | public void testEmptyFilename() { 42 | final String format = FormatNameUtil.formatForFilename(""); 43 | Assert.assertEquals("png", format); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/java/gui/ava/html/renderer/ImageRendererImplTest.java: -------------------------------------------------------------------------------- 1 | package gui.ava.html.renderer; 2 | 3 | import gui.ava.html.BaseTest; 4 | import gui.ava.html.parser.HtmlParserImpl; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | 8 | import java.io.FileOutputStream; 9 | 10 | /** 11 | * @author Yoav Aharoni 12 | */ 13 | public class ImageRendererImplTest extends BaseTest { 14 | private HtmlParserImpl parser; 15 | private ImageRendererImpl renderer; 16 | 17 | @Before 18 | public void createParser() { 19 | parser = new HtmlParserImpl(); 20 | renderer = new ImageRendererImpl(parser); 21 | } 22 | 23 | @Test 24 | public void testSaveStream() throws Exception { 25 | parser.load(getTest1Url()); 26 | renderer.saveImage(new FileOutputStream("file1.png"), true); 27 | } 28 | 29 | @Test 30 | public void testSaveFile() throws Exception { 31 | parser.load(getTest1Url()); 32 | renderer.saveImage("test.gif"); 33 | renderer.saveImage("test.png"); 34 | renderer.saveImage("test.jpg"); 35 | renderer.saveImage("test.bmp"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/resources/test1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | HTML-2-Image Test #1 5 | 21 | 22 | 23 |

24 | Hello 25 | World! 26 |

27 | 28 | 37 | 38 | -------------------------------------------------------------------------------- /trunk/html2image/src/test/resources/test2.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /wiki/Html2Image.wiki: -------------------------------------------------------------------------------- 1 | This is the name of this util. 2 | See [http://code.google.com/p/java-html2image/ html2image] -------------------------------------------------------------------------------- /wiki/HtmlImageGenerator.wiki: -------------------------------------------------------------------------------- 1 | Html2Image as only one useful Java class, *HtmlImageGenerator*. 2 | 3 | Common usage is this: 4 | {{{ 5 | HtmlImageGenerator imageGenerator = new HtmlImageGenerator(); 6 | imageGenerator.loadHtml("Hello World! Please goto Google."); 7 | imageGenerator.saveAsImage("hello-world.png"); 8 | imageGenerator.saveAsHtmlWithMap("hello-world.html", "hello-world.png"); 9 | }}} 10 | 11 | Which will generate _hello-world.png_ image of the HTML and _hello-world.html_ file containing client-side image-map {{{}}} (as in the example above). 12 | 13 | === HtmlImageGenerator Methods === 14 | * *loadUrl(_url_)* - Loads HTML from URL object or URL string. 15 | * *loadHtml(_html_)* - Loads HTML source. 16 | 17 | * *saveAsImage(_file_)* - Save loaded HTML as image. 18 | * *saveAsHtmlWithMap(_file_, _imageUrl_)* - Creates an HTML file containing client-side image-map {{{}}} generated from HTML's links. 19 | 20 | * *getLinks()* - List all links in the HTML document and their corresponding href, target, title, position and dimension. 21 | * *getBufferedImage()* - Get AWT buffered image of the HTML. 22 | * *getLinksMapMarkup(_mapName_)* - Get HTML snippet of the client-side image-map {{{}}} generated from the links. 23 | 24 | * *get/setOrientation(_orientation_)* - Get/Set document orientation (left-to-right or right-to-left). 25 | * *get/setSize(_dimension_)* - Get/Set size of the generated image. --------------------------------------------------------------------------------