JAVA服务端生成图片 -用于分享海报等场景
java

* 基于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,减少了繁琐的模板制作工作量

暂无评论