`

无纸化办公中手写签名的实现

    博客分类:
  • java
 
阅读更多

 

  最近要实现一个使用手写板对PDF文档进行手写签名的功能,下面记录一下关键过程。

 

  实现的思路如下:

1、在画板中显示PDF文档的内容

2、用户使用签名版对PDF文档进行签名

3、保存签名后的画板内容到新的PDF中

 

 其中使用pdfbox把PDF文档转成图片,签名后又把签名后的图片转回PDF保存。

  pdfbox(http://pdfbox.apache.org/)是一个处理PDF文档的JAVA库。

 

Java代码  收藏代码
  1.     import org.apache.pdfbox.pdmodel.PDDocument;  
  2. import org.apache.pdfbox.pdmodel.PDPage;  
  3. import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;  
  4. import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;  
  5. import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;  
  6.   
  7. import javax.imageio.ImageIO;  
  8. import javax.swing.*;  
  9. import java.awt.*;  
  10. import java.awt.event.MouseEvent;  
  11. import java.awt.event.MouseListener;  
  12. import java.awt.event.MouseMotionListener;  
  13. import java.awt.geom.AffineTransform;  
  14. import java.awt.image.AffineTransformOp;  
  15. import java.awt.image.BufferedImage;  
  16. import java.awt.image.ColorModel;  
  17. import java.awt.image.PixelGrabber;  
  18. import java.io.File;  
  19. import java.io.IOException;  
  20. import java.util.logging.Level;  
  21. import java.util.logging.Logger;  
  22.   
  23. class TestDraw extends Canvas {  
  24.     Image image;  
  25.     boolean init = true;  
  26.   
  27.     public static final int WIDTH = 1024;  
  28.   
  29.     public static final int HEIGHT = 1024;  
  30.   
  31.     public Image screen = createImage(WIDTH, HEIGHT, true);// 双缓冲  
  32.   
  33.     private Graphics graphics = screen.getGraphics();  
  34.   
  35.     public Image resultImage;  
  36.   
  37.     int x1 = -1;  
  38.     int y1 = -1;  
  39.     int x2 = -1;  
  40.     int y2 = -1;  
  41.   
  42.     public TestDraw() {  
  43.         this.setBackground(Color.white);  
  44.         this.addMouseListener(new MyMouseListener(this));  
  45.         this.addMouseMotionListener(new MyMouseMotionListener(this));  
  46.   
  47.         image = pdfToImg("pdf/tests.pdf");  
  48.   
  49.         // 设定初始构造时面板大小  
  50.         setPreferredSize(new Dimension(WIDTH, HEIGHT));  
  51.         // 初始导入一张图片  
  52.         ImageIcon icon = new ImageIcon(image);  
  53.         resultImage = icon.getImage();  
  54.   
  55.     }  
  56.   
  57.     public void paint(Graphics g) {  
  58.         update(g);  
  59.     }  
  60.   
  61.     @Override  
  62.     public void update(Graphics g) {  
  63.         BufferedImage bufferedImage= imageToBufferedImage(resultImage);  
  64.   
  65.         // Copy image to buffered image  
  66.         Graphics g2 = bufferedImage.getGraphics();  
  67.         g2.setColor(Color.black);  
  68.         if (x1 == -1 || y1 == -1) {  
  69.             x1 = x2;  
  70.             y1 = y2;  
  71.         }  
  72.         g2.drawLine(x1, y1, x2, y2);  
  73.         x1 = x2;  
  74.         y1 = y2;  
  75.         g2.dispose();  
  76.   
  77.         ImageIcon icon = new ImageIcon(bufferedImage);  
  78.         resultImage = icon.getImage();  
  79.   
  80.         graphics.drawImage(resultImage, 00this);  
  81.         g.drawImage(screen, 00null);// 最后个参数一定要用null,这样可以防止drawImage调用update方法  
  82.         g.dispose();  
  83.     }  
  84.   
  85.   
  86.     public static BufferedImage imageToBufferedImage(Image im) {  
  87.        BufferedImage bi = new BufferedImage  
  88.           (im.getWidth(null),im.getHeight(null),BufferedImage.TYPE_INT_RGB);  
  89.        Graphics bg = bi.getGraphics();  
  90.        bg.drawImage(im, 00null);  
  91.        bg.dispose();  
  92.        return bi;  
  93.     }  
  94.   
  95.     /** 
  96.      * 生成一个BufferImage 
  97.      * 生成一个BufferImage BufferImage是Image的子类,左上角坐标都为 (0, 0) 
  98.      * 第三个参数是代码Image图形类型,分为14种,以位数又分为1,2或4位 
  99.      * 
  100.      * @param width 
  101.      * @param height 
  102.      * @param flag 
  103.      * @return 
  104.      */  
  105.     final static public BufferedImage createImage(int width, int height,  
  106.                                                   boolean flag) {  
  107.         if (flag) {  
  108.             return new BufferedImage(width, height, 2);  
  109.         } else {  
  110.             return new BufferedImage(width, height, 1);  
  111.         }  
  112.     }  
  113.   
  114.     /** 
  115.      * 把PDF转成图片 
  116.      * @param pdfFileName PDF文件路径 
  117.      * @return 
  118.      */  
  119.     public static Image pdfToImg(String pdfFileName) {  
  120.         ImageIcon imageIcon = null;  
  121.         try {  
  122.             PDDocument doc = PDDocument.load(pdfFileName);  
  123.             int pageCount = doc.getNumberOfPages();  
  124.             PDPage page = (PDPage) doc.getDocumentCatalog().getAllPages().get(0);  
  125.             BufferedImage bufferedImage = page.convertToImage();  
  126.             if (bufferedImage != null) {  
  127.                 imageIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(bufferedImage.getSource()));  
  128.             }  
  129.             doc.close();  
  130.         } catch (IOException ex) {  
  131.             Logger.getLogger(ShowJFrame.class.getName()).log(Level.SEVERE, null, ex);  
  132.         }  
  133.         return imageIcon.getImage();  
  134.     }  
  135. }  
  136.   
  137. class MyMouseListener implements MouseListener {  
  138.     TestDraw draw;  
  139.   
  140.     public MyMouseListener(TestDraw draw) {  
  141.         this.draw = draw;  
  142.     }  
  143.   
  144.     /** 
  145.      * 点击鼠标时保存新的PDF文件 
  146.      * @param e 
  147.      */  
  148.     public void mouseClicked(MouseEvent e) {  
  149.         System.out.println("mouseClicked");  
  150.   
  151.         PDDocument doc = null;  
  152.         PDPage page = null;  
  153.   
  154.         try {  
  155.             doc = new PDDocument();  
  156.             page = new PDPage();  
  157.   
  158.             BufferedImage bufferedImage = toBufferedImage(draw.resultImage);  
  159.             File outputfile = new File("saved.png");  
  160.                ImageIO.write(bufferedImage, "png", outputfile);  
  161.   
  162.             int w = bufferedImage.getWidth();  
  163.             int h = bufferedImage.getHeight();  
  164.             BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
  165.             AffineTransform at = new AffineTransform();  
  166.             at.scale(0.50.5);  
  167.             AffineTransformOp scaleOp =  
  168.                new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);  
  169.             after = scaleOp.filter(bufferedImage, after);  
  170.   
  171.             doc.addPage(page);  
  172.             PDXObjectImage ximage = new PDJpeg(doc, after);  
  173.             PDPageContentStream content = new PDPageContentStream(doc, page, truetrue);  
  174. //            content.drawImage(ximage, 0, 0);  
  175.             content.drawXObject(ximage, 00800800);  
  176.             content.close();  
  177.             doc.save("save.pdf");  
  178.             doc.close();  
  179.         } catch (Exception ex) {  
  180.             System.out.println(ex);  
  181.         }  
  182.     }  
  183.   
  184.     // This method returns a buffered image with the contents of an image  
  185.     public static BufferedImage toBufferedImage(Image image) {  
  186.         if (image instanceof BufferedImage) {  
  187.             return (BufferedImage) image;  
  188.         }  
  189.   
  190.         // This code ensures that all the pixels in the image are loaded  
  191.         image = new ImageIcon(image).getImage();  
  192.   
  193.         // Determine if the image has transparent pixels; for this method's  
  194.         // implementation, see e661 Determining If an Image Has Transparent Pixels  
  195.         boolean hasAlpha = hasAlpha(image);  
  196.   
  197.         // Create a buffered image with a format that's compatible with the screen  
  198.         BufferedImage bimage = null;  
  199.         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();  
  200.         try {  
  201.             // Determine the type of transparency of the new buffered image  
  202.             int transparency = Transparency.OPAQUE;  
  203.             if (hasAlpha) {  
  204.                 transparency = Transparency.BITMASK;  
  205.             }  
  206.   
  207.             // Create the buffered image  
  208.             GraphicsDevice gs = ge.getDefaultScreenDevice();  
  209.             GraphicsConfiguration gc = gs.getDefaultConfiguration();  
  210.             bimage = gc.createCompatibleImage(  
  211.                 image.getWidth(null), image.getHeight(null), transparency);  
  212.         } catch (HeadlessException e) {  
  213.             // The system does not have a screen  
  214.         }  
  215.   
  216.         if (bimage == null) {  
  217.             // Create a buffered image using the default color model  
  218.             int type = BufferedImage.TYPE_INT_RGB;  
  219.             if (hasAlpha) {  
  220.                 type = BufferedImage.TYPE_INT_ARGB;  
  221.             }  
  222.             bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);  
  223.         }  
  224.   
  225.         // Copy image to buffered image  
  226.         Graphics g = bimage.createGraphics();  
  227.   
  228.         // Paint the image onto the buffered image  
  229.         g.drawImage(image, 00null);  
  230.         g.dispose();  
  231.   
  232.         return bimage;  
  233.     }  
  234.   
  235.     //Determining If an Image Has Transparent Pixels  
  236.   
  237.     // This method returns true if the specified image has transparent pixels  
  238.     public static boolean hasAlpha(Image image) {  
  239.         // If buffered image, the color model is readily available  
  240.         if (image instanceof BufferedImage) {  
  241.             BufferedImage bimage = (BufferedImage) image;  
  242.             return bimage.getColorModel().hasAlpha();  
  243.         }  
  244.   
  245.         // Use a pixel grabber to retrieve the image's color model;  
  246.         // grabbing a single pixel is usually sufficient  
  247.         PixelGrabber pg = new PixelGrabber(image, 0011false);  
  248.         try {  
  249.             pg.grabPixels();  
  250.         } catch (InterruptedException e) {  
  251.         }  
  252.   
  253.         // Get the image's color model  
  254.         ColorModel cm = pg.getColorModel();  
  255.         return cm.hasAlpha();  
  256.     }  
  257.   
  258.     public void mouseEntered(MouseEvent e) {  
  259.         //System.out.println("mouseEntered");  
  260.     }  
  261.   
  262.     public void mouseExited(MouseEvent e) {  
  263.         //System.out.println("mouseExited");  
  264.     }  
  265.   
  266.     public void mousePressed(MouseEvent e) {  
  267.         //System.out.println("mousePressed");  
  268.         draw.x1 = -1;  
  269.         draw.y1 = -1;  
  270.     }  
  271.   
  272.     public void mouseReleased(MouseEvent e) {  
  273.         //System.out.println("mouseReleased");  
  274.         draw.x1 = draw.x2;  
  275.         draw.y1 = draw.y2;  
  276.     }  
  277. }  
  278.   
  279. class MyMouseMotionListener implements MouseMotionListener {  
  280.     TestDraw draw;  
  281.   
  282.     public MyMouseMotionListener(TestDraw draw) {  
  283.         this.draw = draw;  
  284.     }  
  285.   
  286.     public void mouseDragged(MouseEvent e) {  
  287.         //System.out.println("mouseDragged");  
  288.         draw.x2 = e.getX();  
  289.         draw.y2 = e.getY();  
  290.         draw.repaint();  
  291.     }  
  292.   
  293.     public void mouseMoved(MouseEvent e) {  
  294.         //System.out.println("mouseMoved");  
  295.     }  
  296. }  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics