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
linkxxx 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");
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 {{{