java-证件照合成

发布时间 2023-04-19 16:09:36作者: 一缕清风丶

工具类:

  1 package com.test1;
  2 
  3 import javax.imageio.ImageIO;
  4 import javax.swing.*;
  5 import java.awt.*;
  6 import java.awt.image.BufferedImage;
  7 import java.io.ByteArrayInputStream;
  8 import java.io.File;
  9 import java.io.IOException;
 10 import java.net.URL;
 11 import java.util.Base64;
 12 import java.util.Map;
 13 
 14 /**
 15  * @author cjq
 16  * 身份证件工具类
 17  */
 18 public class IdCardUtil {
 19 
 20     private Font font = new Font("华文细黑", Font.PLAIN, 18);// 添加字体的属性设置
 21 
 22     private Graphics2D g = null;
 23 
 24     private int fontsize = 0;
 25 
 26     private int x = 0;
 27 
 28     private int y = 0;
 29 
 30     public static int color_range = 210;
 31 
 32     /**
 33      * 导入本地图片到缓冲区
 34      */
 35     public BufferedImage loadImageLocal(String imgName) {
 36         try {
 37             return ImageIO.read(new File(imgName));
 38         } catch (IOException e) {
 39             System.out.println(e.getMessage());
 40         }
 41         return null;
 42     }
 43 
 44     /**
 45      * 导入网络图片到缓冲区
 46      */
 47     public BufferedImage loadImageUrl(String imgName) {
 48         try {
 49             URL url = new URL(imgName);
 50             return ImageIO.read(url);
 51         } catch (IOException e) {
 52             System.out.println(e.getMessage());
 53         }
 54         return null;
 55     }
 56 
 57     /**
 58      * 生成新图片到本地
 59      */
 60     public void writeImageLocal(String newImage, BufferedImage img) {
 61         if (newImage != null && img != null) {
 62             try {
 63                 File outputfile = new File(newImage);
 64                 ImageIO.write(img, "jpg", outputfile);
 65             } catch (IOException e) {
 66                 System.out.println(e.getMessage());
 67             }
 68         }
 69     }
 70 
 71     /**
 72      * 设定文字的字体等
 73      */
 74     public void setFont(String fontStyle, int fontSize) {
 75         this.fontsize = fontSize;
 76         this.font = new Font(fontStyle, Font.BOLD, fontSize); //
 77     }
 78 
 79     /**
 80      * 修改图片,返回修改后的图片缓冲区(只输出一行文本)
 81      */
 82     public BufferedImage modifyImage(BufferedImage img, Object content, int x,
 83                                      int y) {
 84 
 85         try {
 86             int w = img.getWidth();
 87             int h = img.getHeight();
 88             g = img.createGraphics();
 89             g.setBackground(Color.black);
 90             g.setColor(Color.black);//设置字体颜色
 91             if (this.font != null) {
 92                 g.setFont(this.font);
 93             }
 94             // 验证输出位置的纵坐标和横坐标
 95             if (x >= h || y >= w) {
 96                 this.x = h - this.fontsize + 2;
 97                 this.y = w;
 98             } else {
 99                 this.x = x;
100                 this.y = y;
101             }
102             if (content != null) {
103                 g.drawString(content.toString(), this.x, this.y);
104             }
105             g.dispose();
106         } catch (Exception e) {
107             System.out.println(e.getMessage());
108         }
109 
110         return img;
111     }
112 
113     /**
114      * 图像合成
115      * @param b
116      * @param d
117      * @return
118      */
119     public BufferedImage modifyImagetogeter(BufferedImage b, BufferedImage d) {
120         try {
121 //            int w = b.getWidth();
122 //            int h = b.getHeight();
123             g = d.createGraphics();
124             g.drawImage(b, 330, 35, 180, 200, null); //调整粘贴图片的位置
125             g.dispose();
126         } catch (Exception e) {
127             System.out.println(e.getMessage());
128         }
129         return d;
130     }
131 
132     /**
133      * 指定身份证号码解析
134      * @param result
135      * @param idno
136      */
137     public void defineIdno(Map<String, String> result, String idno) {
138         String sex = idno.substring(16, 17);
139         int i = Integer.parseInt(sex);
140         if (i % 2 == 0) {
141             sex = "";//M
142         } else {
143             sex = "";//F
144         }
145         result.put("IdCardNo", idno.replaceAll(""," "));//更改身份证
146         result.put("year", idno.substring(6, 10));//更改年
147         result.put("month", idno.substring(10, 12));//更改月
148         result.put("day", idno.substring(12, 14));//更改日
149         result.put("sex", sex);//性别
150     }
151 
152 
153     /**
154      * base64 编码转换为 BufferedImage
155      * 图片白底转透明
156      * @param base64
157      * @return
158      */
159     public BufferedImage base64ToBufferedImage(String base64) {
160         Base64.Decoder decoder = Base64.getDecoder();
161         try {
162             byte[] bytes1 = decoder.decode(base64);
163             ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
164             BufferedImage bufferedImage = ImageIO.read(bais);
165             //  图片白底转透明
166             ImageIcon imageIcon = new ImageIcon(bufferedImage);
167             BufferedImage bf = new BufferedImage(
168                     imageIcon.getIconWidth(), imageIcon.getIconHeight(),
169                     BufferedImage.TYPE_4BYTE_ABGR);
170             Graphics2D g2D = (Graphics2D) bf.getGraphics();
171             g2D.drawImage(imageIcon.getImage(), 0, 0,
172                     imageIcon.getImageObserver());
173             int alpha;
174             for (int j1 = bf.getMinY(); j1 < bf
175                     .getHeight(); j1++) {
176                 for (int j2 = bf.getMinX(); j2 < bf
177                         .getWidth(); j2++) {
178                     int rgb = bf.getRGB(j2, j1);
179                     if (colorInRange(rgb)) {
180                         alpha = 0;
181                     } else {
182                         alpha = 255;
183                     }
184                     rgb = (alpha << 24) | (rgb & 0x00ffffff);
185                     bf.setRGB(j2, j1, rgb);
186                 }
187             }
188             g2D.drawImage(bf, 0, 0, imageIcon.getImageObserver());
189             return bf;
190         } catch (IOException e) {
191             e.printStackTrace();
192         }
193         return null;
194     }
195 
196     /**
197      * 转rgb
198      * @param color
199      * @return
200      */
201     public boolean colorInRange(int color) {
202         int red = (color & 0xff0000) >> 16;
203         int green = (color & 0x00ff00) >> 8;
204         int blue = (color & 0x0000ff);
205         if (red >= color_range && green >= color_range && blue >= color_range) {
206             return true;
207         }
208         return false;
209     }
210 }

证件照正面生成

 1 package com.test1;
 2 
 3 import java.awt.image.BufferedImage;
 4 import java.util.ArrayList;
 5 import java.util.HashMap;
 6 import java.util.List;
 7 import java.util.Map;
 8 
 9 public class IDCardFront {
10     /**
11      * 身份证正面
12      *
13      * @param args
14      */
15     public static void main(String[] args) {
16         IdCardUtil tt = new IdCardUtil();
17         Map<String, String> result = new HashMap<>();
18         tt.defineIdno(result, "330200XXXXXXXXXXXX");
19         String name = "张三";
20         String address = "新疆伊宁县吉里于孜镇XX社区XXX路XXXXXXXX号楼X单元XXX室";
21         String fileName = "F:\\IdcodeGenerater-master\\" + name + "Front.jpg"; //生成文件名
22         BufferedImage d = tt.loadImageLocal("F:\\IdcodeGenerater-master\\sfzzm.jpg"); //证件照正面模板
23 //        BufferedImage b = tt.loadImageLocal("F:\\IdcodeGenerater-master\\cjq.jpg");
24         String base64 = "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";
25         BufferedImage b = tt.base64ToBufferedImage(base64);
26         //合并图片
27         tt.writeImageLocal(fileName, tt.modifyImagetogeter(b, d));
28         //往图片上写文字
29         tt.writeImageLocal(fileName, tt.modifyImage(d, name, 85, 50)); //姓名
30         tt.writeImageLocal(fileName, tt.modifyImage(d, result.get("sex"), 85, 95)); //性别
31         tt.writeImageLocal(fileName, tt.modifyImage(d, "", 205, 95)); //民族
32         tt.writeImageLocal(fileName, tt.modifyImage(d, result.get("year") + "           " + result.get("month") + "      " + result.get("day"), 85, 137)); //出生年月
33 
34         List<String> data = new ArrayList<String>();
35         int iLen = address.length();
36         while (iLen >= 11) {
37             String tmp = address.substring(0, 11);
38             data.add(tmp);
39             address = address.substring(11);
40             iLen = address.length();
41         }
42         for (int i = 0; i < data.size(); i++) {
43             tt.writeImageLocal(fileName, tt.modifyImage(d, data.get(i), 85, 183 + 18 * i)); //住址
44         }
45         tt.writeImageLocal(fileName, tt.modifyImage(d, result.get("IdCardNo"), 170, 292)); //身份证号
46         //将多张图片合在一起
47         System.out.println("身份证正面生成成功~!");
48     }
49 }

 

证件照反面生成

 1 package com.test1;
 2 
 3 import java.awt.image.BufferedImage;
 4 
 5 public class IDCardReverse {
 6 
 7     /**
 8      * 身份证反面
 9      *
10      * @param args
11      */
12     public static void main(String[] args) {
13         IdCardUtil tt = new IdCardUtil();
14         String name = "张三";
15         String fileName = "F:\\IdcodeGenerater-master\\" + name + "Back.jpg"; //生成文件名
16         BufferedImage d = tt.loadImageLocal("F:\\IdcodeGenerater-master\\sfzfm.jpg"); //证件照反面模板
17         String police = "伊宁县公安局";
18         String userlifeb = "20210329";
19         String userlifee = "20410329";
20         StringBuffer sb1 = new StringBuffer();
21         sb1.append(userlifeb).insert(4, ".").insert(7, ".").append("-").append(userlifee).insert(15, ".").insert(18, ".");
22         //往图片上写文字
23         tt.writeImageLocal(fileName, tt.modifyImage(d, police, 250, 265)); //签发机关
24         tt.writeImageLocal(fileName, tt.modifyImage(d, sb1.toString(), 250, 308)); //有效期限
25         //将多张图片合在一起
26         System.out.println("身份证反面生成成功~!");
27     }
28 }