java图片嵌套合成
常见的需要把背景图跟二维码合成或者头像等一些列合成,这里做个多图片或文字合成演示:
来张合成后的效果
这张图片由微信头像,个人二维码,个人微信昵称,其他背景图等合成一张照片
上工具代码
package com.sr.biofunet.web.controller.utils; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.View; import javax.swing.text.ViewFactory; import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.HTMLEditorKit.HTMLFactory; import javax.swing.text.html.ImageView; public class SynchronousHTMLEditorKit extends HTMLEditorKit { public Document createDefaultDocument() { HTMLDocument doc = (HTMLDocument)super.createDefaultDocument(); doc.setAsynchronousLoadPriority(-1); return doc; } public ViewFactory getViewFactory() { return new HTMLFactory() { public View create(Element elem) { View view = super.create(elem); if ((view instanceof ImageView)) { ((ImageView)view).setLoadsSynchronously(true); } return view; } }; } }
package com.sr.biofunet.web.controller.utils; import java.awt.Rectangle; import java.util.List; import java.util.Map; public class LinkInfo { private Map<String, String> attributes; private List<Rectangle> bounds; public LinkInfo(Map<String, String> attributes, List<Rectangle> bounds) { this.attributes = attributes; this.bounds = bounds; } public Map<String, String> getAttributes() { return this.attributes; } public List<Rectangle> getBounds() { return this.bounds; } }
package com.sr.biofunet.web.controller.utils; import java.awt.Rectangle; import java.util.ArrayList; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JEditorPane; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Element; import javax.swing.text.JTextComponent; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.html.HTML; import javax.swing.text.html.HTML.Attribute; import javax.swing.text.html.HTML.Tag; public class LinkHarvester { private final JTextComponent textComponent; private final List<LinkInfo> links = new ArrayList(); public LinkHarvester(JEditorPane textComponent) { this.textComponent = textComponent; harvestElement(textComponent.getDocument().getDefaultRootElement()); } public List<LinkInfo> getLinks() { return this.links; } private void harvestElement(Element element) { if (element == null) { return; } AttributeSet attributes = element.getAttributes(); Enumeration attributeNames = attributes.getAttributeNames(); while (attributeNames.hasMoreElements()) { Object key = attributeNames.nextElement(); if (Tag.A.equals(key)) { Map linkAttributes = harvestAttributes(element); List bounds = harvestBounds(element); if ((!linkAttributes.isEmpty()) && (!bounds.isEmpty())) { this.links.add(new LinkInfo(linkAttributes, bounds)); } } } for (int i = 0; i < element.getElementCount(); i++) { Element child = element.getElement(i); harvestElement(child); } } private Map<String, String> harvestAttributes(Element element) { Object value = element.getAttributes().getAttribute(Tag.A); if ((value instanceof SimpleAttributeSet)) { SimpleAttributeSet attributeSet = (SimpleAttributeSet)value; Map result = new HashMap(); addAttribute(attributeSet, result, Attribute.HREF); addAttribute(attributeSet, result, Attribute.TARGET); addAttribute(attributeSet, result, Attribute.TITLE); addAttribute(attributeSet, result, Attribute.CLASS); addAttribute(attributeSet, result, "tabindex"); addAttribute(attributeSet, result, "dir"); addAttribute(attributeSet, result, "lang"); addAttribute(attributeSet, result, "accesskey"); addAttribute(attributeSet, result, "onblur"); addAttribute(attributeSet, result, "onclick"); addAttribute(attributeSet, result, "ondblclick"); addAttribute(attributeSet, result, "onfocus"); addAttribute(attributeSet, result, "onmousedown"); addAttribute(attributeSet, result, "onmousemove"); addAttribute(attributeSet, result, "onmouseout"); addAttribute(attributeSet, result, "onmouseover"); addAttribute(attributeSet, result, "onmouseup"); addAttribute(attributeSet, result, "onkeydown"); addAttribute(attributeSet, result, "onkeypress"); addAttribute(attributeSet, result, "onkeyup"); return result; } return Collections.emptyMap(); } private void addAttribute(SimpleAttributeSet attributeSet, Map<String, String> result, Object attribute) { String attName = attribute.toString(); String attValue = (String)attributeSet.getAttribute(attribute); if ((attValue != null) && (!attValue.equals(""))) result.put(attName, attValue); } private List<Rectangle> harvestBounds(Element element) { List boundsList = new ArrayList(); try { int startOffset = element.getStartOffset(); int endOffset = element.getEndOffset(); Rectangle lastBounds = null; for (int i = startOffset; i <= endOffset; i++) { Rectangle bounds = this.textComponent.modelToView(i); if (bounds == null) { continue; } if (lastBounds == null) { lastBounds = bounds; } else if (bounds.getY() == lastBounds.getY()) { lastBounds = lastBounds.union(bounds); } else { if ((lastBounds.getWidth() > 1.0D) && (lastBounds.getHeight() > 1.0D)) { boundsList.add(lastBounds); } lastBounds = null; } } if ((lastBounds != null) && (lastBounds.getWidth() > 1.0D) && (lastBounds.getHeight() > 1.0D)) { boundsList.add(lastBounds); } return boundsList; } catch (BadLocationException e) { } throw new RuntimeException("Got BadLocationException"); } }
package com.sr.biofunet.web.controller.utils; import java.awt.ComponentOrientation; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.net.URL; import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import javax.imageio.ImageIO; import javax.swing.JEditorPane; public class HtmlImageGenerator { private JEditorPane editorPane = this.createJEditorPane(); static final Dimension DEFAULT_SIZE = new Dimension(800, 800); public HtmlImageGenerator() { } public ComponentOrientation getOrientation() { return this.editorPane.getComponentOrientation(); } public void setOrientation(ComponentOrientation orientation) { this.editorPane.setComponentOrientation(orientation); } public Dimension getSize() { return this.editorPane.getSize(); } public void setSize(Dimension dimension) { this.editorPane.setSize(dimension); } public void loadUrl(URL url) { try { this.editorPane.setPage(url); } catch (IOException var3) { throw new RuntimeException(String.format("Exception while loading %s", new Object[]{url}), var3); } } public void loadUrl(String url) { try { this.editorPane.setPage(url); } catch (IOException var3) { throw new RuntimeException(String.format("Exception while loading %s", new Object[]{url}), var3); } } public void loadHtml(String html) { this.editorPane.setText(html); this.onDocumentLoad(); } public String getLinksMapMarkup(String mapName) { StringBuilder markup = new StringBuilder(); markup.append("<map name=\"").append(mapName).append("\">\n"); Iterator i$ = this.getLinks().iterator(); while(i$.hasNext()) { LinkInfo link = (LinkInfo)i$.next(); List bounds = link.getBounds(); Iterator i$1 = bounds.iterator(); while(i$1.hasNext()) { Rectangle bound = (Rectangle)i$1.next(); int x1 = (int)bound.getX(); int y1 = (int)bound.getY(); int x2 = (int)((double)x1 + bound.getWidth()); int y2 = (int)((double)y1 + bound.getHeight()); markup.append(String.format("<area coords=\"%s,%s,%s,%s\" shape=\"rect\"", new Object[]{Integer.valueOf(x1), Integer.valueOf(y1), Integer.valueOf(x2), Integer.valueOf(y2)})); Iterator i$2 = link.getAttributes().entrySet().iterator(); while(i$2.hasNext()) { Entry entry = (Entry)i$2.next(); String attName = (String)entry.getKey(); String value = (String)entry.getValue(); markup.append(" ").append(attName).append("=\"").append(value.replace("\"", """)).append("\""); } markup.append(">\n"); } } markup.append("</map>\n"); return markup.toString(); } public List<LinkInfo> getLinks() { LinkHarvester harvester = new LinkHarvester(this.editorPane); return harvester.getLinks(); } public void saveAsHtmlWithMap(String file, String imageUrl) { this.saveAsHtmlWithMap(new File(file), imageUrl); } public void saveAsHtmlWithMap(File file, String imageUrl) { FileWriter writer = null; try { writer = new FileWriter(file); writer.append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"); writer.append("<html>\n<head></head>\n"); writer.append("<body style=\"margin: 0; padding: 0; text-align: center;\">\n"); String e = this.getLinksMapMarkup("map"); writer.write(e); writer.append("<img border=\"0\" usemap=\"#map\" src=\""); writer.append(imageUrl); writer.append("\"/>\n"); writer.append("</body>\n</html>"); } catch (IOException var12) { throw new RuntimeException(String.format("Exception while saving \'%s\' html file", new Object[]{file}), var12); } finally { if(writer != null) { try { writer.close(); } catch (IOException var11) { ; } } } } public void saveAsImage(String file) { this.saveAsImage(new File(file)); } public void saveAsImage(File file) { BufferedImage img = this.getBufferedImage(); try { String e = FormatNameUtil.formatForFilename(file.getName()); ImageIO.write(img, e, file); } catch (IOException var4) { throw new RuntimeException(String.format("Exception while saving \'%s\' image", new Object[]{file}), var4); } } protected void onDocumentLoad() { } public Dimension getDefaultSize() { return DEFAULT_SIZE; } public BufferedImage getBufferedImage() { Dimension prefSize = this.editorPane.getPreferredSize(); BufferedImage img = new BufferedImage(prefSize.width, this.editorPane.getPreferredSize().height, 2); Graphics graphics = img.getGraphics(); this.editorPane.setSize(prefSize); this.editorPane.paint(graphics); return img; } protected JEditorPane createJEditorPane() { JEditorPane editorPane = new JEditorPane(); editorPane.setSize(this.getDefaultSize()); editorPane.setEditable(false); SynchronousHTMLEditorKit kit = new SynchronousHTMLEditorKit(); editorPane.setEditorKitForContentType("text/html", kit); editorPane.setContentType("text/html"); editorPane.addPropertyChangeListener(new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if(evt.getPropertyName().equals("page")) { HtmlImageGenerator.this.onDocumentLoad(); } } }); return editorPane; } }
package com.sr.biofunet.web.controller.utils; import java.util.HashMap; import java.util.Map; public class FormatNameUtil { public static Map<String, String> types = new HashMap(); private static final String DEFAULT_FORMAT = "png"; public static String formatForExtension(String extension) { String type = (String)types.get(extension); if (type == null) { return "png"; } return type; } public static String formatForFilename(String fileName) { int dotIndex = fileName.lastIndexOf(46); if (dotIndex < 0) { return "png"; } String ext = fileName.substring(dotIndex + 1); return formatForExtension(ext); } static { types.put("gif", "gif"); types.put("jpg", "jpg"); types.put("jpeg", "jpg"); types.put("png", "png"); } }
下面来是重点,调用工具合成
public String generateAgentQrCode(String openID, String qrcodeUrlS,HttpServletRequest request,String headUrl,String nickName) { String agentQrCode = ""; HtmlImageGenerator imageGenerator = new HtmlImageGenerator(); String htmlstr = " <div style=\"height:648px;width:100%;padding:30px 10px 0 10px;\">\n" + " <table width=\"100%\" style=\"vertical-align:top;\">\n" + " <tr>\n" + " <td colspan=\"3\">\n" + " <table style=\"background: #f2f2f2;width: 100%;border: 10px solid #e4c5b8;padding: 30px 0;margin-bottom:6px\">\n" + " <tr >\n" + " <td rowspan=\"2\" style=\"padding-left:8%;width:260px;height:260px;vertical-align: middle;border-radius: 50%;overflow: hidden;text-align: center;background-size: 100%\" >\n" + " <img src=\"" +headUrl +"\" width=\"220\" height=\"220\" style=\"border-radius: 50%\" >\n" + " </td>\n" + " <td style=\"padding-left: 8%;font-size:30px;\">I'm "+nickName+"</td>\n" + " </tr>\n" + " <tr>\n" + " <td style=\"text-align:left;padding-left: 8%\">\n" + " <img src=\"http://localhost:8888/biofunetUpload//image/20170725/7062330ebcf24a9383605018b326e158.png\" >\n" + " </td>\n" + " </tr>\n" + " </table>\n" + " </td>\n" + " </tr>\n" + "\n" + "\n" + " <tr >\n" + " <td style=\"text-align:left;\" colspan=\"3\">\n" + " <img src=\"http://localhost:8888/biofunetUpload//image/20170725/1bff72172396475da1076ec1adf9ddf0.png\" width=\"100%\">\n" + " </td>\n" + " </tr>\n" + " <tr>\n" + " <td ></td>\n" + " <td style=\"text-align:left;padding:10px 0 0 20px\">\n" + " <img src=\"http://localhost:8888/biofunetUpload//image/20170725/7f2f0c74c06e4274800b0ff4c3dbe033.png\" >\n" + " </td>\n" + " <td style=\"text-align:right;padding:10px 0 0 20px\">\n" + " <img src=\"" + qrcodeUrlS+ "\"" + " </td>\n" + " </tr>\n" + " </table>\n" + " </div>"; imageGenerator.loadHtml(htmlstr); imageGenerator.getBufferedImage(); String path = request.getRealPath("/"); File fileParent = new File(path + "uploads" + File.separator); if (!fileParent.exists()) { fileParent.mkdir(); } /** 保存图片 **/ String filePath = path + "uploads"+File.separator + openID + "_QrCode.png"; imageGenerator.saveAsImage(filePath); //到此图片已经合成了 /** 上传图片服务器 **/ String resultString = HttpConnectionUtil.uploadFile(FINALSTR.SERVERURL + "newUpload", openID + "_QrCode.png", filePath); System.out.print("resultString================" + resultString); if (StringUtils.isNotBlank(resultString)) { JSONObject jsonObject = JSONObject.parseObject(resultString); if (jsonObject != null && jsonObject.containsKey("map")) { JSONObject mapJSON = JSONObject.parseObject(jsonObject.getString("map")); agentQrCode = mapJSON.getString("uri"); } } return FINALSTR.SERVERURL + agentQrCode; }
上面的只是个案例,
下面提供一个下载指定ip下的文件的方法
package com.sr.biofunet.web.controller.utils; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSession; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.net.URL; import java.net.URLConnection; /** * Created by Administrator on 2017/7/18 0018. */ public class DownLoadQrCode { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub // https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQFH8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyVm1rZ0VkSmVh download("https://mp.weixin.qqS9AAAAA", "111.png","c:\\image\\"); } public static void download(String urlString, String filename,String savePath) throws Exception { InputStream is = null; OutputStream os = null; try { HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session) { System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; // 构造URL URL url = new URL(urlString); trustAllHttpsCertificates(); HttpsURLConnection.setDefaultHostnameVerifier(hv); // 打开连接 URLConnection con = url.openConnection(); //设置请求超时为5s con.setConnectTimeout(5 * 1000); // 输入流 is = con.getInputStream(); // 1K的数据缓冲 byte[] bs = new byte[1024]; // 读取到的数据长度 int len; // 输出的文件流 File sf = new File(savePath); if (!sf.exists()) { sf.mkdirs(); } os = new FileOutputStream(sf.getPath() + File.separator + filename); // 开始读取 while ((len = is.read(bs)) != -1) { os.write(bs, 0, len); } }catch (Exception e){ e.printStackTrace(); }finally { if(is!=null){ is.close(); } if(os!=null){ os.flush(); // 完毕,关闭所有链接 os.close(); } } } private static void trustAllHttpsCertificates() throws Exception { javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; javax.net.ssl.TrustManager tm = new miTM(); trustAllCerts[0] = tm; javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext .getInstance("SSL"); sc.init(null, trustAllCerts, null); javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc .getSocketFactory()); } static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted( java.security.cert.X509Certificate[] certs) { return true; } public boolean isClientTrusted( java.security.cert.X509Certificate[] certs) { return true; } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } } }
本节完