* 基于HTML生成图片
方案1 基于AWT or Swing 的Panel生成
JEditorPane ed = new JEditorPane(new URL("http://www.google.com"));
ed.setSize(200,200);
BufferedImage image = new BufferedImage(ed.getWidth(), ed.getHeight(),BufferedImage.TYPE_INT_ARGB);
SwingUtilities.paintComponent(image.createGraphics(), ed, new JPanel(), 0, 0, image.getWidth(), image.getHeight());
//save the image to file
ImageIO.write((RenderedImage)image, "png", new File("html.png"));
缺点:需要单独部署http服务器,用户访问数据, 优点: 不需要第三依赖
方案2 基于lib库 生成
下载地址:http://code.google.com/p/java-html2image/
HtmlImageGenerator imageGenerator = new HtmlImageGenerator();
imageGenerator.loadHtml(htmText);
imageGenerator.getBufferedImage();
imageGenerator.saveAsImage(saveImageLocation);
//imageGenerator.saveAsHtmlWithMap("hello-world.html", saveImageLocation);
BufferedImage sourceImg = ImageIO.read(new File(saveImageLocation));
sourceImg = transform_Gray24BitMap(sourceImg);
ImageIO.write(sourceImg, "BMP", new File(saveImageLocation));
缺点:css 大量不兼容,文字模糊,优点:接入简单 适合一些比较css不复杂的html
方案3 基于canvas的截图
参考 Puppeteer https://github.com/puppeteer/puppeteer
const puppeteer = require('puppeteer')
const parallel = 5;
(async () => {
puppeteer.launch().then(async browser => {
const promises = []
for (let i = 0; i < parallel; i++) {
console.log('Page ID Spawned', i)
promises.push(browser.newPage().then(async page => {
await page.setViewport({ width: 1280, height: 800 })
await page.goto('https://en.wikipedia.org/wiki/' + i)
await page.screenshot({ path: 'wikipedia_' + i + '.png' })
}))
}
await Promise.all(promises)
await browser.close()
})
})()
基于Puppeteer 生成的图片 很清晰,性能取决于浏览器的加载速度,缺点 就是需要维添加puppeteer依赖,与java进行嵌入
基于pdf生成图片
参考: pdfbox https://pdfbox.apache.org/ ; itexfpdf https://itextpdf.com/en
设计思路 ,
1.编写带有pdf表单的模板
2.读取模板,动态替换表单内容,生成新的pdf
3.pdf转图片
FileOutputStream out = new FileOutputStream(newPDFPath);
PdfReader reader = new PdfReader(templatePath);//读取pdf模板
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, bos);
AcroFields form = stamper.getAcroFields(); //生成form表单数据
form.setField("name", "xxxx");
form.setField("duties", "管理员");
form.setField("mobile", "1234567");
stamper.close();
//生成新的pdf
Document doc = new Document();
PdfCopy copy = new PdfCopy(doc, out);
doc.open();
PdfImportedPage importPage = copy.getImportedPage(new PdfReader(bos.toByteArray()), 1);
copy.addPage(importPage);
doc.close();
//转换成图片
PDDocument document = PDDocument.load(new File(newPDFPath));
PDFRenderer pdfRenderer = new PDFRenderer(document);
BufferedImage bim = pdfRenderer.renderImageWithDPI(0, 500);
ImageIOUtil.writeImage(bim, newPDFPath + ".png", 0);
缺点: 需要开发pdf模板,字体需要单独嵌入,容易错版
基于svg生成图片
设计思路: svg使用 XML 格式定义图像 ,所以做一个xml内容模板,使用 freemarker替换部分内容,在将生成后的svg转图片
参考 :batik https://xmlgraphics.apache.org/batik/
StringWriter stringWriter = new StringWriter();
Template freemarkerTemplate = freemarkerConfiguration.getTemplate("cartTemplate.ftl");
Map<String, String> data = new HashMap<>();
data.put("userName", "xxxx");
data.put("userDuties", "xxxxxx");
freemarkerTemplate.process(data, stringWriter);
stringWriter.flush();//生成svg的xml内容
//batik 转换为图片
StringReader stringReader = new StringReader(template);
String parser = XMLResourceDescriptor.getXMLParserClassName();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(parser);
Document doc = f.createSVGDocument(null, stringReader);
PNGTranscoder t = new PNGTranscoder();
TranscoderInput input = new TranscoderInput(doc);
TranscoderOutput output = new TranscoderOutput(outputStream);
t.transcode(input, output);
outputStream.flush();
最终采用的SVG 生成图片的方案,生成的图片清晰度较高 大小可控,且可以由UI 的原始图片直接转换为SVG,减少了繁琐的模板制作工作量