精华内容
下载资源
问答
  • 移动开发现在是一个非常火爆的行业,那么作为扫一扫就可以添加神器——微信的二维码来说,那自然也是相当的牛逼的了。  不多说了,先看看要生成一个二维码,需要几步?  1.准备工作,一个生成二维码中间的...

            移动开发现在是一个非常火爆的行业,那么作为扫一扫就可以添加神器——微信的二维码来说,那自然也是相当的牛逼的了。

            不多说了,先看看要生成一个二维码,需要几步?


            1.准备工作,一个生成二维码中间的图标,可选择;一个是第三方的工具,java这边的话生成二维码有很多开发的jar包如 zxing,qrcode( 前者是谷歌开发的后者则是小日本开发的 ,这里的话我使用zxing的开发包来弄。


            2.到网站上去下载zxing包。 http://code.google.com/p/zxing/ 可以选择版本下载.


            3.直接上干货,不需要过多的配置操作。


            代码片一:


    public class BufferedImageLuminanceSource extends LuminanceSource {


        private final BufferedImage image;
        private final int left;
        private final int top;

        public BufferedImageLuminanceSource(BufferedImage image) {
            this(image, 0, 0, image.getWidth(), image.getHeight());
        }

        public BufferedImageLuminanceSource(BufferedImage image, int left,
                int top, int width, int height) {
            super(width, height);

            int sourceWidth = image.getWidth();
            int sourceHeight = image.getHeight();
            if (left + width > sourceWidth || top + height > sourceHeight) {
                throw new IllegalArgumentException(
                        "Crop rectangle does not fit within image data.");
            }

            for (int y = top; y < top + height; y++) {
                for (int x = left; x < left + width; x++) {
                    if ((image.getRGB(x, y) & 0xFF000000) == 0) {
                        image.setRGB(x, y, 0xFFFFFFFF); // = white
                    }
                }
            }

            this.image = new BufferedImage(sourceWidth, sourceHeight,
                    BufferedImage.TYPE_BYTE_GRAY);
            this.image.getGraphics().drawImage(image, 0, 0, null);
            this.left = left;
            this.top = top;
        }

        
        public byte[] getRow(int y, byte[] row) {
            if (y < 0 || y >= getHeight()) {
                throw new IllegalArgumentException(
                        "Requested row is outside the image: " + y);
            }
            int width = getWidth();
            if (row == null || row.length < width) {
                row = new byte[width];
            }
            image.getRaster().getDataElements(left, top + y, width, 1, row);
            return row;
        }

        
        public byte[] getMatrix() {
            int width = getWidth();
            int height = getHeight();
            int area = width * height;
            byte[] matrix = new byte[area];
            image.getRaster().getDataElements(left, top, width, height, matrix);
            return matrix;
        }

        
        public boolean isCropSupported() {
            return true;
        }

        
        public LuminanceSource crop(int left, int top, int width, int height) {
            return new BufferedImageLuminanceSource(image, this.left + left,
                    this.top + top, width, height);
        }

        
        public boolean isRotateSupported() {
            return true;
        }

        
        public LuminanceSource rotateCounterClockwise() {
            int sourceWidth = image.getWidth();
            int sourceHeight = image.getHeight();
            AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0,
                    0.0, 0.0, sourceWidth);
            BufferedImage rotatedImage = new BufferedImage(sourceHeight,
                    sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
            Graphics2D g = rotatedImage.createGraphics();
            g.drawImage(image, transform, null);
            g.dispose();
            int width = getWidth();
            return new BufferedImageLuminanceSource(rotatedImage, top,
                    sourceWidth - (left + width), getHeight(), width);
        }

    }



    生成二维码代码片二:


    /**
     * 二维码工具类
     *
     */
    public class CodeUtil {

        private static final String CHARSET = "utf-8";
        private static final String FORMAT_NAME = "JPG";
        // 二维码尺寸
        private static final int QRCODE_SIZE = 300;
        // LOGO宽度
        private static final int WIDTH = 60;
        // LOGO高度
        private static final int HEIGHT = 60;

        private static BufferedImage createImage(String content, String imgPath,
                boolean needCompress) throws Exception {
            Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
            hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
            hints.put(EncodeHintType.MARGIN, 1);
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
                    BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
            int width = bitMatrix.getWidth();
            int height = bitMatrix.getHeight();
            BufferedImage image = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
                            : 0xFFFFFFFF);
                }
            }
            if (imgPath == null || "".equals(imgPath)) {
                return image;
            }
            // 插入图片
            CodeUtil.insertImage(image, imgPath, needCompress);
            return image;
        }

        /**
         * 插入LOGO
         *
         * @param source
         *            二维码图片
         * @param imgPath
         *            LOGO图片地址
         * @param needCompress
         *            是否压缩
         * @throws Exception
         */
        private static void insertImage(BufferedImage source, String imgPath,
                boolean needCompress) throws Exception {
            File file = new File(imgPath);
            if (!file.exists()) {
                System.err.println(""+imgPath+"   该文件不存在!");
                return;
            }
            Image src = ImageIO.read(new File(imgPath));
            int width = src.getWidth(null);
            int height = src.getHeight(null);
            if (needCompress) { // 压缩LOGO
                if (width > WIDTH) {
                    width = WIDTH;
                }
                if (height > HEIGHT) {
                    height = HEIGHT;
                }
                Image image = src.getScaledInstance(width, height,
                        Image.SCALE_SMOOTH);
                BufferedImage tag = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);
                Graphics g = tag.getGraphics();
                g.drawImage(image, 0, 0, null); // 绘制缩小后的图
                g.dispose();
                src = image;
            }
            // 插入LOGO
            Graphics2D graph = source.createGraphics();
            int x = (QRCODE_SIZE - width) / 2;
            int y = (QRCODE_SIZE - height) / 2;
            graph.drawImage(src, x, y, width, height, null);
            Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
            graph.setStroke(new BasicStroke(3f));
            graph.draw(shape);
            graph.dispose();
        }

        /**
         * 生成二维码(内嵌LOGO)
         *
         * @param content
         *            内容
         * @param imgPath
         *            LOGO地址
         * @param destPath
         *            存放目录
         * @param needCompress
         *            是否压缩LOGO
         * @throws Exception
         */
        public static void encode(String content, String imgPath, String destPath,
                boolean needCompress) throws Exception {
            BufferedImage image = CodeUtil.createImage(content, imgPath,
                    needCompress);
            mkdirs(destPath);
            String file = new Random().nextInt(99999999)+".jpg";
            ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
        }

        /**
         * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
         */
        public static void mkdirs(String destPath) {
            File file =new File(destPath);    
            //当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
            if (!file.exists() && !file.isDirectory()) {
                file.mkdirs();
            }
        }

        /**
         * 生成二维码(内嵌LOGO)
         *
         * @param content
         *            内容
         * @param imgPath
         *            LOGO地址
         * @param destPath
         *            存储地址
         * @throws Exception
         */
        public static void encode(String content, String imgPath, String destPath)
                throws Exception {
            CodeUtil.encode(content, imgPath, destPath, false);
        }

        /**
         * 生成二维码
         *
         * @param content
         *            内容
         * @param destPath
         *            存储地址
         * @param needCompress
         *            是否压缩LOGO
         * @throws Exception
         */
        public static void encode(String content, String destPath,
                boolean needCompress) throws Exception {
            CodeUtil.encode(content, null, destPath, needCompress);
        }

        /**
         * 生成二维码
         *
         * @param content
         *            内容
         * @param destPath
         *            存储地址
         * @throws Exception
         */
        public static void encode(String content, String destPath) throws Exception {
            CodeUtil.encode(content, null, destPath, false);
        }

        /**
         * 生成二维码(内嵌LOGO)
         *
         * @param content
         *            内容
         * @param imgPath
         *            LOGO地址
         * @param output
         *            输出流
         * @param needCompress
         *            是否压缩LOGO
         * @throws Exception
         */
        public static void encode(String content, String imgPath,
                OutputStream output, boolean needCompress) throws Exception {
            BufferedImage image = CodeUtil.createImage(content, imgPath,
                    needCompress);
            ImageIO.write(image, FORMAT_NAME, output);
        }

        /**
         * 生成二维码
         *
         * @param content
         *            内容
         * @param output
         *            输出流
         * @throws Exception
         */
        public static void encode(String content, OutputStream output)
                throws Exception {
            CodeUtil.encode(content, null, output, false);
        }

        /**
         * 解析二维码
         *
         * @param file
         *            二维码图片
         * @return
         * @throws Exception
         */
        public static String decode(File file) throws Exception {
            BufferedImage image;
            image = ImageIO.read(file);
            if (image == null) {
                return null;
            }
            BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(
                    image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
            Result result;
            Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
            hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
            result = new MultiFormatReader().decode(bitmap, hints);
            String resultStr = result.getText();
            return resultStr;
        }

        /**
         * 解析二维码
         *
         * @param path
         *            二维码图片地址
         * @return
         * @throws Exception
         */
        public static String decode(String path) throws Exception {
            return CodeUtil.decode(new File(path));
        }

        public static void main(String[] args) throws Exception {
            String text = "http://www.baidu.com";
            CodeUtil.encode(text, "f:/baidu.jpg", "f:/code", true);
        }
    }


    4.

    问题总结:

    1. ZXing扫描二维码出现中文乱码的问题:

     ZXing 扫条形码没有问题,但是扫描二维码的时候却有一部分是乱码,或者不是中文的问题。

    只要以ISO- 8859 - 1 的格式来编码,取出结果再进行相应的转换,问题就解决了,并不需要修改源码,可以参考上面的代码。

    2. 报错:java.lang.UnsupportedClassVersionError: com/google/zxing/client/j2se/MatrixToImageWriter

    遇到这个问题的话,98%的概率是JDK的版本与ZXing版不搭了,上面已经说过了,2.2版本在JDK1.6应该是没问题的,2.3的话应该是对JDK1.7有依赖了。

    使用者在使用这个的时候要注意,防止出现了问题。



    展开全文
  • javaweb之二维码

    2017-11-21 19:37:52
    考虑到如果一个用户发布一个app的话,便于推广,一般需要将其下载地址封装到二维码中去,当前比较火热的移动端系统,安卓和iso系统,下载链接是不一样的,ios需要链接到苹果商店里面,为了实现一码多用,实现这么一...

    考虑到如果一个用户发布一个app的话,便于推广,一般需要将其下载地址封装到二维码中去,当前比较火热的移动端系统,安卓和iso系统,下载链接是不一样的,ios需要链接到苹果商店里面,为了实现一码多用,实现这么一个功能,做了这个小系统(也是为了完成作业,好像给加分闭嘴--!)


     执行步骤:

       1、用户在前台表单提交APP的IOS和Android下载地址。

      2、后台接收IOS和Android下载地址然后生成一个UUID,把这三个信息存储在数据库中。

      3、定义一个@RequestMapping地址,通过地址中传递的UUID,在数据库中查询到IOS和Android

      4、把当前服务器的网址+@RequestMapping地址+UUID合成二维码返回给前端显示

      5、用户扫描的二维码实际上是访问了我们事先定义的@RequestMapping地址,通过用户的http请求,我们可以获取到用户的手机操作系统是IOS还是Android,这样就可以跳转到指定的地址了。

      项目选型,我使用Spring SpringMVC MyBatis现在最流行的框架,然后用maven搭建项目,在二维码的生成和解析的时候,使用google的zxing jar。

      添加的依赖pom.xml

    [html]  view plain  copy
    1.     
    2.   <dependencies>  
    3.      <!-- freemarker依赖 -->  
    4.      <dependency>  
    5.        <groupId>org.freemarker</groupId>  
    6.        <artifactId>freemarker</artifactId>  
    7.        <version>${freemarker.version}</version>  
    8.      </dependency>  
    9.         
    10.     <!-- spring mvc 框架 -->  
    11.     <dependency>  
    12.         <groupId>org.springframework</groupId>  
    13.         <artifactId>spring-webmvc</artifactId>  
    14.         <version>${spring.version}</version>  
    15.     </dependency>  
    16.         
    17.         <dependency>    
    18.             <groupId>org.springframework</groupId>    
    19.             <artifactId>spring-jdbc</artifactId>    
    20.             <version>${spring.version}</version>    
    21.         </dependency>  
    22.           
    23.         <dependency>    
    24.             <groupId>org.springframework</groupId>    
    25.             <artifactId>spring-context-support</artifactId>    
    26.             <version>${spring.version}</version>    
    27.         </dependency>  
    28.           
    29.         <dependency>    
    30.             <groupId>org.springframework</groupId>    
    31.             <artifactId>spring-test</artifactId>    
    32.             <version>${spring.version}</version>    
    33.         </dependency>   
    34.           
    35.         <dependency>  
    36.             <groupId>c3p0</groupId>  
    37.             <artifactId>c3p0</artifactId>  
    38.              <version>0.9.1.2</version>  
    39.         </dependency>  
    40.           
    41.          <!-- 导入Mysql数据库链接jar包 -->    
    42.         <dependency>  
    43.             <groupId>mysql</groupId>  
    44.             <artifactId>mysql-connector-java</artifactId>  
    45.             <version>5.1.4</version>  
    46.         </dependency>   
    47.           
    48.         <!-- mybatis核心包 -->    
    49.         <dependency>    
    50.             <groupId>org.mybatis</groupId>    
    51.             <artifactId>mybatis</artifactId>    
    52.             <version>${mybatis.version}</version>    
    53.         </dependency>    
    54.         <!-- mybatis/spring包 -->    
    55.         <dependency>    
    56.             <groupId>org.mybatis</groupId>    
    57.             <artifactId>mybatis-spring</artifactId>    
    58.             <version>1.2.2</version>    
    59.         </dependency>   
    60.           
    61.          <!-- 上传组件包 -->    
    62.         <dependency>    
    63.             <groupId>commons-fileupload</groupId>    
    64.             <artifactId>commons-fileupload</artifactId>    
    65.             <version>1.3.1</version>    
    66.         </dependency>    
    67.         <dependency>    
    68.             <groupId>commons-io</groupId>    
    69.             <artifactId>commons-io</artifactId>    
    70.             <version>2.4</version>    
    71.         </dependency>    
    72.         <dependency>    
    73.             <groupId>commons-codec</groupId>    
    74.             <artifactId>commons-codec</artifactId>    
    75.             <version>1.9</version>    
    76.         </dependency>   
    77.       
    78.     <!-- servlet -->  
    79.     <dependency>  
    80.         <groupId>javax.servlet</groupId>  
    81.         <artifactId>servlet-api</artifactId>  
    82.         <version>2.5</version>  
    83.     </dependency>  
    84.       
    85.     <!-- jsp/jstl/core 页面标签 -->  
    86.     <dependency>  
    87.         <groupId>javax.servlet</groupId>  
    88.         <artifactId>jstl</artifactId>  
    89.         <version>1.2</version>  
    90.     </dependency>  
    91.     <dependency>  
    92.         <groupId>taglibs</groupId>  
    93.         <artifactId>standard</artifactId>  
    94.         <version>1.1.2</version>  
    95.     </dependency>  
    96.       
    97.     <!-- SLF4J API -->  
    98.     <!-- SLF4J 是一个日志抽象层,允许你使用任何一个日志系统,并且可以随时切换还不需要动到已经写好的程序 -->  
    99.     <dependency>  
    100.         <groupId>org.slf4j</groupId>  
    101.         <artifactId>slf4j-api</artifactId>  
    102.         <version>1.7.22</version>  
    103.     </dependency>  
    104.       
    105.     <!-- Log4j 日志系统(最常用) -->  
    106.     <dependency>  
    107.         <groupId>org.slf4j</groupId>  
    108.         <artifactId>slf4j-log4j12</artifactId>  
    109.         <version>1.7.22</version>  
    110.     </dependency>  
    111.       
    112.     <!-- jackson -->  
    113.     <dependency>  
    114.         <groupId>com.fasterxml.jackson.core</groupId>  
    115.         <artifactId>jackson-core</artifactId>  
    116.         <version>${jackson.version}</version>  
    117.     </dependency>  
    118.     <dependency>  
    119.         <groupId>com.fasterxml.jackson.core</groupId>  
    120.         <artifactId>jackson-annotations</artifactId>  
    121.         <version>${jackson.version}</version>  
    122.     </dependency>  
    123.     <dependency>  
    124.         <groupId>com.fasterxml.jackson.core</groupId>  
    125.         <artifactId>jackson-databind</artifactId>  
    126.         <version>${jackson.version}</version>  
    127.     </dependency>  
    128.         
    129.     <dependency>  
    130.       <groupId>junit</groupId>  
    131.       <artifactId>junit</artifactId>  
    132.       <version>3.8.1</version>  
    133.       <scope>test</scope>  
    134.     </dependency>  
    135.       
    136.     <!-- 谷歌的zxingjar包 -->  
    137.     <dependency>  
    138.         <groupId>com.google.zxing</groupId>  
    139.         <artifactId>core</artifactId>  
    140.         <version>3.1.0</version>  
    141.     </dependency>  
    142.       
    143.     <dependency>    
    144.         <groupId>com.google.zxing</groupId>    
    145.         <artifactId>javase</artifactId>    
    146.         <version>3.0.0</version>    
    147.     </dependency>   
    148.       
    149.        
    150.       
    151.     <!-- swagger2整合springmvc快速生成rest风格接口文档 -->  
    152.     <dependency>  
    153.         <groupId>io.springfox</groupId>  
    154.         <artifactId>springfox-swagger2</artifactId>  
    155.         <version>2.5.0</version>  
    156.     </dependency>  
    157.     <dependency>  
    158.         <groupId>io.springfox</groupId>  
    159.         <artifactId>springfox-swagger-ui</artifactId>  
    160.         <version>2.5.0</version>  
    161.     </dependency>  
    162.       
    163.   </dependencies>  
    164.     
    165.   <build>  
    166.     <finalName>spring-mvc-web</finalName>  
    167.   </build>  
    168. </project>  

    二维码生成、解析工具类ZXingCodeUtil.java 

    [java]  view plain  copy

    1.   
    2. import java.awt.Color;  
    3. import java.awt.Font;  
    4. import java.awt.Graphics2D;  
    5. import java.awt.image.BufferedImage;  
    6. import java.io.ByteArrayOutputStream;  
    7. import java.io.File;  
    8. import java.io.IOException;  
    9.   
    10. import java.util.HashMap;  
    11. import java.util.Map;  
    12. import javax.imageio.ImageIO;  
    13. import javax.servlet.http.HttpServletRequest;  
    14. import com.google.zxing.BarcodeFormat;  
    15. import com.google.zxing.Binarizer;  
    16. import com.google.zxing.BinaryBitmap;  
    17. import com.google.zxing.DecodeHintType;  
    18. import com.google.zxing.EncodeHintType;  
    19. import com.google.zxing.LuminanceSource;  
    20. import com.google.zxing.MultiFormatReader;  
    21. import com.google.zxing.MultiFormatWriter;  
    22. import com.google.zxing.NotFoundException;  
    23. import com.google.zxing.Result;  
    24. import com.google.zxing.WriterException;  
    25. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;  
    26. import com.google.zxing.common.BitMatrix;  
    27. import com.google.zxing.common.HybridBinarizer;  
    28. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
    29.   
    30.   
    31. /** 
    32.  * @Description: (二维码生成工具类) 
    33.  * @author 苏叶biubiu 
    34.  */  
    35. public class ZXingCodeUtil {  
    36.     private static final int QRCOLOR = 0xFF000000;   //默认是黑色  
    37.     private static final int BGWHITE = 0xFFFFFFFF;   //背景颜色  
    38.   
    39.   
    40.     public static void main(String[] args) throws WriterException{    
    41.         try {    
    42.             //getLogoQRCode("https://www.baidu.com/", null, "跳转到百度的二维码");  
    43.             //getQRCode("https://www.baidu.com/", null, "跳转到百度的二维码");  
    44.               
    45.         }    
    46.         catch (Exception e)  {    
    47.             e.printStackTrace();    
    48.         }    
    49.     }    
    50.       
    51.     /** 
    52.      * 二维码解析 
    53.      * @param file 二维码图片文件 
    54.      * @return 解析结果 
    55.      */  
    56.     public static String parseQRCode(File file) {  
    57.         BufferedImage image;    
    58.         try {    
    59.             image = ImageIO.read(file);    
    60.             LuminanceSource source = new BufferedImageLuminanceSource(image);    
    61.             Binarizer binarizer = new HybridBinarizer(source);    
    62.             BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);    
    63.             Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();    
    64.             hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");    
    65.             Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码    
    66.             return result.getText();  
    67.         } catch (IOException e) {    
    68.             e.printStackTrace();   
    69.             return null;  
    70.         } catch (NotFoundException e) {    
    71.             e.printStackTrace();  
    72.             return null;  
    73.         }    
    74.     }  
    75.       
    76.       
    77.     /** 
    78.      * 生成不带logo的二维码 
    79.      * @param qrUrl 链接地址 
    80.      * @param request 请求 
    81.      * @param productName 二维码名称 
    82.      * @param file 上传路径+文件名 
    83.      * @return 
    84.      */  
    85.     public static String getQRCode(String qrUrl,HttpServletRequest request,String productName,File file ) {  
    86.         // String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png";  
    87.         //filePath是二维码logo的路径,但是实际中我们是放在项目的某个路径下面的,所以路径用上面的,把下面的注释就好  
    88.           
    89.         String content = qrUrl;  
    90.         try {    
    91.             ZXingCodeUtil zp = new ZXingCodeUtil();  
    92.             BufferedImage image = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 400400, zp.getDecodeHintType());  
    93.             image.flush();  
    94.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    95.             baos.flush();  
    96.             ImageIO.write(image, "png", baos);  
    97.             //二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉  
    98.             //可以看到这个方法最终返回的是这个二维码的imageBase64字符串  
    99.             //前端用 <img src="data:image/png;base64,${imageBase64QRCode}"/> 其中${imageBase64QRCode}对应二维码的imageBase64字符串  
    100.             //new File("E:/" + new Date().getTime() + "test.png")  
    101.             //判断目标文件所在的目录是否存在    
    102.             if(!file.getParentFile().exists()) {    
    103.                 //如果目标文件所在的目录不存在,则创建父目录    
    104.                 System.out.println("目标文件所在目录不存在,准备创建它!");    
    105.                 if(!file.getParentFile().mkdirs()) {    
    106.                     System.out.println("创建目标文件所在目录失败!");    
    107.                 }    
    108.             }  
    109.             ImageIO.write(image, "png", file);   
    110.              
    111.             String imageBase64QRCode =  new sun.misc.BASE64Encoder().encodeBuffer(baos.toByteArray());  
    112.             baos.close();  
    113.             return imageBase64QRCode;  
    114.         }  
    115.         catch (Exception e){  
    116.             e.printStackTrace();  
    117.         }  
    118.         return null;  
    119.     }  
    120.   
    121.     /** 
    122.      * 生成带logo的二维码图片 
    123.      * @param qrUrl 链接地址 
    124.      * @param request 请求 
    125.      * @param productName 二维码名称 
    126.      * @param logoFile logo文件 
    127.      * @param createFile 生成的文件路径 
    128.      * @return 
    129.      */  
    130.     public static String getLogoQRCode(String qrUrl,HttpServletRequest request,String productName,File logoFile,File createFile) {  
    131.         // String filePath = request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png";  
    132.         //filePath是二维码logo的路径,但是实际中我们是放在项目的某个路径下面的,所以路径用上面的,把下面的注释就好  
    133.         String content = qrUrl;  
    134.         try{    
    135.             ZXingCodeUtil zp = new ZXingCodeUtil();  
    136.             BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 400400, zp.getDecodeHintType());  
    137.             return zp.addLogo_QRCode(bim, logoFile , new LogoConfig(), productName, createFile);  
    138.         }  
    139.         catch (Exception e) {  
    140.             e.printStackTrace();  
    141.         }  
    142.         return null;  
    143.     }  
    144.   
    145.     /** * 给二维码图片添加Logo * * @param qrPic * @param logoPic */  
    146.     public String addLogo_QRCode(BufferedImage bim, File logoPic, LogoConfig logoConfig, String productName, File createFile) {  
    147.         try {  
    148.             /** * 读取二维码图片,并构建绘图对象 */  
    149.             BufferedImage image = bim;  
    150.             Graphics2D g = image.createGraphics();  
    151.   
    152.             /** * 读取Logo图片 */  
    153.             BufferedImage logo = ImageIO.read(logoPic);  
    154.             /** * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码 */  
    155.             int widthLogo = logo.getWidth(null)>image.getWidth()*3/10?(image.getWidth()*3/10):logo.getWidth(null),   
    156.                 heightLogo = logo.getHeight(null)>image.getHeight()*3/10?(image.getHeight()*3/10):logo.getWidth(null);  
    157.   
    158.             /** * logo放在中心 */  
    159.              int x = (image.getWidth() - widthLogo) / 2;  
    160.              int y = (image.getHeight() - heightLogo) / 2;  
    161.              /** * logo放在右下角 * int x = (image.getWidth() - widthLogo); * int y = (image.getHeight() - heightLogo); */  
    162.   
    163.             //开始绘制图片  
    164.             g.drawImage(logo, x, y, widthLogo, heightLogo, null);  
    165.             // g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);  
    166.             // g.setStroke(new BasicStroke(logoConfig.getBorder()));  
    167.             // g.setColor(logoConfig.getBorderColor());  
    168.             // g.drawRect(x, y, widthLogo, heightLogo);  
    169.             g.dispose();  
    170.   
    171.             //把商品名称添加上去,商品名称不要太长哦,这里最多支持两行。太长就会自动截取啦  
    172.             if (productName != null && !productName.equals("")) {  
    173.                 //新的图片,把带logo的二维码下面加上文字  
    174.                 BufferedImage outImage = new BufferedImage(400445, BufferedImage.TYPE_4BYTE_ABGR);  
    175.                 Graphics2D outg = outImage.createGraphics();  
    176.                 //画二维码到新的面板  
    177.                 outg.drawImage(image, 00, image.getWidth(), image.getHeight(), null);  
    178.                 //画文字到新的面板  
    179.                 outg.setColor(Color.BLACK);   
    180.                 outg.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号   
    181.                 int strWidth = outg.getFontMetrics().stringWidth(productName);  
    182.                 if (strWidth > 399) {  
    183.                     // //长度过长就截取前面部分  
    184.                     // outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //画文字  
    185.                     //长度过长就换行  
    186.                     String productName1 = productName.substring(0, productName.length()/2);  
    187.                     String productName2 = productName.substring(productName.length()/2, productName.length());  
    188.                     int strWidth1 = outg.getFontMetrics().stringWidth(productName1);  
    189.                     int strWidth2 = outg.getFontMetrics().stringWidth(productName2);  
    190.                     outg.drawString(productName1, 200  - strWidth1/2, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 );  
    191.                     BufferedImage outImage2 = new BufferedImage(400485, BufferedImage.TYPE_4BYTE_ABGR);  
    192.                     Graphics2D outg2 = outImage2.createGraphics();  
    193.                     outg2.drawImage(outImage, 00, outImage.getWidth(), outImage.getHeight(), null);  
    194.                     outg2.setColor(Color.BLACK);   
    195.                     outg2.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号   
    196.                     outg2.drawString(productName2, 200  - strWidth2/2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight())/2 + 5 );  
    197.                     outg2.dispose();   
    198.                     outImage2.flush();  
    199.                     outImage = outImage2;  
    200.                 }else {  
    201.                     outg.drawString(productName, 200  - strWidth/2 , image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 ); //画文字   
    202.                 }  
    203.                 outg.dispose();   
    204.                 outImage.flush();  
    205.                 image = outImage;  
    206.             }  
    207.             logo.flush();  
    208.             image.flush();  
    209.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
    210.             baos.flush();  
    211.             ImageIO.write(image, "png", baos);  
    212.   
    213.             //二维码生成的路径,但是实际项目中,我们是把这生成的二维码显示到界面上的,因此下面的折行代码可以注释掉  
    214.             //可以看到这个方法最终返回的是这个二维码的imageBase64字符串  
    215.             //前端用 <img src="data:image/png;base64,${imageBase64QRCode}"/> 其中${imageBase64QRCode}对应二维码的imageBase64字符串  
    216.             if(!createFile.getParentFile().exists()) {    
    217.                 //如果目标文件所在的目录不存在,则创建父目录    
    218.                 System.out.println("目标文件所在目录不存在,准备创建它!");    
    219.                 if(!createFile.getParentFile().mkdirs()) {    
    220.                     System.out.println("创建目标文件所在目录失败!");    
    221.                 }    
    222.             }  
    223.             ImageIO.write(image, "png", createFile);   
    224.              
    225.             String imageBase64QRCode =  new sun.misc.BASE64Encoder().encodeBuffer(baos.toByteArray());  
    226.             baos.close();  
    227.             return imageBase64QRCode;  
    228.         }  
    229.         catch (Exception e){  
    230.             e.printStackTrace();  
    231.         }  
    232.         return null;  
    233.     }  
    234.   
    235.   
    236.     /** * 构建初始化二维码 * * @param bm * @return */  
    237.     public BufferedImage fileToBufferedImage(BitMatrix bm){  
    238.         BufferedImage image = null;  
    239.         try  
    240.         {  
    241.             int w = bm.getWidth(), h = bm.getHeight();  
    242.             image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
    243.   
    244.             for (int x = 0; x < w; x++)  
    245.             {  
    246.                 for (int y = 0; y < h; y++)  
    247.                 {  
    248.                     image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);  
    249.                 }  
    250.             }  
    251.   
    252.         }  
    253.         catch (Exception e){  
    254.             e.printStackTrace();  
    255.         }  
    256.         return image;  
    257.     }  
    258.   
    259.     /** * 生成二维码bufferedImage图片 * * @param content * 编码内容 * @param barcodeFormat * 编码类型 * @param width * 图片宽度 * @param height * 图片高度 * @param hints * 设置参数 * @return */  
    260.     public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints) {  
    261.         MultiFormatWriter multiFormatWriter = null;  
    262.         BitMatrix bm = null;  
    263.         BufferedImage image = null;  
    264.         try{  
    265.             multiFormatWriter = new MultiFormatWriter();  
    266.             // 参数顺序分别为:编码内容,编码类型,生成图片宽度,生成图片高度,设置参数  
    267.             bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);  
    268.             int w = bm.getWidth();  
    269.             int h = bm.getHeight();  
    270.             image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);  
    271.   
    272.             // 开始利用二维码数据创建Bitmap图片,分别设为黑(0xFFFFFFFF)白(0xFF000000)两色  
    273.             for (int x = 0; x < w; x++){  
    274.                 for (int y = 0; y < h; y++) {  
    275.                     image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE);  
    276.                 }  
    277.             }  
    278.         }  
    279.         catch (WriterException e){  
    280.             e.printStackTrace();  
    281.         }  
    282.         return image;  
    283.     }  
    284.   
    285.     /** * 设置二维码的格式参数 * * @return */  
    286.     public Map<EncodeHintType, Object> getDecodeHintType() {  
    287.         // 用于设置QR二维码参数  
    288.         Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();  
    289.         // 设置QR二维码的纠错级别(H为最高级别)具体级别信息  
    290.         hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);  
    291.         // 设置编码方式  
    292.         hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
    293.         hints.put(EncodeHintType.MARGIN, 0);  
    294.         hints.put(EncodeHintType.MAX_SIZE, 350);  
    295.         hints.put(EncodeHintType.MIN_SIZE, 100);  
    296.   
    297.         return hints;  
    298.     }  
    299. }  
    300.   
    301.     class LogoConfig {  
    302.         // logo默认边框颜色  
    303.         public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;  
    304.         // logo默认边框宽度  
    305.         public static final int DEFAULT_BORDER = 2;  
    306.         // logo大小默认为照片的1/5  
    307.         public static final int DEFAULT_LOGOPART = 5;  
    308.   
    309.         private final int border = DEFAULT_BORDER;  
    310.         private final Color borderColor;  
    311.         private final int logoPart;  
    312.   
    313.         /** * Creates a default config with on color {@link #BLACK} and off color * {@link #WHITE}, generating normal black-on-white barcodes. */  
    314.         public LogoConfig(){  
    315.             this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);  
    316.         }  
    317.   
    318.         public LogoConfig(Color borderColor, int logoPart){  
    319.             this.borderColor = borderColor;  
    320.             this.logoPart = logoPart;  
    321.         }  
    322.   
    323.         public Color getBorderColor() {  
    324.             return borderColor;  
    325.         }  
    326.   
    327.         public int getBorder(){  
    328.             return border;  
    329.         }  
    330.   
    331.         public int getLogoPart() {  
    332.             return logoPart;  
    333.         }  
    334.     }  
     8位短uuid生成工具类

    [java]  view plain  copy

    1.   
    2. import java.awt.Color;  
    3. import java.awt.Font;  
    4. import java.awt.Graphics2D;  
    5. import java.awt.image.BufferedImage;  
    6. import java.io.ByteArrayOutputStream;  
    7. import java.io.File;  
    8. import java.io.IOException;  
    9. import java.util.Date;  
    10. import java.util.HashMap;  
    11. import java.util.Map;  
    12. import java.util.UUID;  
    13.   
    14. import javax.imageio.ImageIO;  
    15. import javax.servlet.http.HttpServletRequest;  
    16. import com.google.zxing.BarcodeFormat;  
    17. import com.google.zxing.EncodeHintType;  
    18. import com.google.zxing.MultiFormatWriter;  
    19. import com.google.zxing.WriterException;  
    20. import com.google.zxing.common.BitMatrix;  
    21. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;  
    22.   
    23.   
    24. /** 
    25.  * @Description: 短uuid生成 
    26.  * @author 苏叶biubiu 
    27.  */  
    28. public class UuidUtil {  
    29.      
    30.   
    31.   
    32.     public static void main(String[] args) throws WriterException{    
    33.         String uuid = generateShortUuid();  
    34.         System.out.println(uuid);  
    35.     }    
    36.   
    37.     public static String[] chars = new String[] { "a""b""c""d""e""f",    
    38.         "g""h""i""j""k""l""m""n""o""p""q""r""s",    
    39.         "t""u""v""w""x""y""z""0""1""2""3""4""5",    
    40.         "6""7""8""9""A""B""C""D""E""F""G""H""I",    
    41.         "J""K""L""M""N""O""P""Q""R""S""T""U""V",    
    42.         "W""X""Y""Z" };    
    43.   
    44.   
    45.     public static String generateShortUuid() {    
    46.         StringBuffer shortBuffer = new StringBuffer();    
    47.         String uuid = UUID.randomUUID().toString().replace("-""");    
    48.         for (int i = 0; i < 8; i++) {    
    49.             String str = uuid.substring(i * 4, i * 4 + 4);    
    50.             int x = Integer.parseInt(str, 16);    
    51.             shortBuffer.append(chars[x % 0x3E]);    
    52.         }    
    53.         return shortBuffer.toString();    
    54.       
    55.     }    
    56.       
    57.       
    58.       
    59. }  
    60.   
    61.      

    核心控制器

    [java]  view plain  copy

    1.   
    2. import java.io.BufferedInputStream;  
    3. import java.io.File;    
    4. import java.io.FileNotFoundException;  
    5. import java.io.FileOutputStream;  
    6. import java.io.IOException;  
    7. import java.io.InputStream;  
    8. import java.io.OutputStream;  
    9. import java.net.HttpURLConnection;  
    10. import java.net.URL;  
    11. import java.util.Date;    
    12. import java.util.HashMap;  
    13. import java.util.Map;  
    14.     
    15. import javax.servlet.http.HttpServletRequest;    
    16. import javax.servlet.http.HttpServletResponse;  
    17.     
    18. import org.slf4j.Logger;  
    19. import org.slf4j.LoggerFactory;  
    20. import org.springframework.beans.factory.annotation.Autowired;  
    21. import org.springframework.stereotype.Controller;    
    22. import org.springframework.ui.ModelMap;    
    23. import org.springframework.web.bind.annotation.RequestMapping;    
    24. import org.springframework.web.bind.annotation.RequestMethod;  
    25. import org.springframework.web.bind.annotation.RequestParam;    
    26. import org.springframework.web.bind.annotation.ResponseBody;  
    27. import org.springframework.web.multipart.MultipartFile;    
    28. import org.springframework.web.multipart.MultipartHttpServletRequest;  
    29. import org.springframework.web.multipart.commons.CommonsMultipartFile;  
    30.   
    31. import com.jiafuwei.spring.po.JsonResult;  
    32. import com.jiafuwei.spring.po.QRCode;  
    33. import com.jiafuwei.spring.service.IQRCodeService;  
    34. import com.jiafuwei.spring.util.UuidUtil;  
    35. import com.jiafuwei.spring.util.ZXingCodeUtil;  
    36.     
    37. @Controller    
    38. public class UploadController {    
    39.     final Logger logger = LoggerFactory.getLogger(getClass());  
    40.       
    41.     @Autowired  
    42.     private IQRCodeService qRCodeService;  
    43.    
    44.     /* 
    45.      * 通过流的方式上传文件 
    46.      * @RequestParam("file") 将name=file控件得到的文件封装成CommonsMultipartFile 对象 
    47.      */  
    48.     @RequestMapping("fileUpload")  
    49.     public String  fileUpload(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request,  
    50.             ModelMap model) throws IOException {  
    51.            
    52.            
    53.         //用来检测程序运行时间  
    54.         long  startTime=System.currentTimeMillis();  
    55.         String path = request.getSession().getServletContext().getRealPath("upload");   
    56.         String fileName = file.getOriginalFilename();  
    57.         System.out.println("fileName:"+fileName);  
    58.           
    59.         File targetFile = new File(path, fileName);    
    60.         if(!targetFile.exists()){    
    61.             targetFile.mkdirs();    
    62.         }   
    63.         file.transferTo(targetFile);  
    64.           
    65.         model.addAttribute("fileUrl", request.getContextPath()+"/upload/"+fileName);    
    66.           
    67.          
    68.         long  endTime=System.currentTimeMillis();  
    69.         System.out.println("方法一的运行时间:"+String.valueOf(endTime-startTime)+"ms");  
    70.         return "/result";   
    71.     }  
    72.     
    73.       
    74.     @RequestMapping("fileUploadLogo")  
    75.     @ResponseBody  
    76.     public String  fileUploadLogo(@RequestParam("file") CommonsMultipartFile file,HttpServletRequest request,  
    77.             ModelMap model) throws IOException {  
    78.            
    79.            
    80.         //用来检测程序运行时间  
    81.         long  startTime=System.currentTimeMillis();  
    82.         String path = request.getSession().getServletContext().getRealPath("upload");   
    83.         String fileName = file.getOriginalFilename();  
    84.         System.out.println("fileName:"+fileName);  
    85.           
    86.         File targetFile = new File(path, fileName);    
    87.         if(!targetFile.exists()){    
    88.             targetFile.mkdirs();    
    89.         }   
    90.         file.transferTo(targetFile);  
    91.           
    92.         model.addAttribute("fileUrl", request.getContextPath()+"/upload/"+fileName);    
    93.           
    94.          
    95.         long  endTime=System.currentTimeMillis();  
    96.         System.out.println("方法一的运行时间:"+String.valueOf(endTime-startTime)+"ms");  
    97.         return "result";   
    98.     }  
    99.       
    100.     /** 
    101.      * APP 合成二维码生成 
    102.      * @param request 
    103.      * @param model 
    104.      * @return 
    105.      * @throws IOException 
    106.      */  
    107.     @RequestMapping("synthesisQRCode")  
    108.     @ResponseBody  
    109.     public JsonResult  SynthesisQRCode(HttpServletRequest request,  
    110.             @RequestParam(value="file",required=false) CommonsMultipartFile logoFile,  
    111.             @RequestParam(value="ios_url",required=true) String ios_url,  
    112.             @RequestParam(value="android_url",required=true) String android_url,  
    113.             ModelMap model) throws IOException {  
    114.           
    115.          logger.info("SynthesisQRCode - {}""开始了");  
    116.          logger.info("path - {}", request.getSession().getServletContext().getRealPath("/"));  
    117.            
    118.          StringBuffer url = request.getRequestURL();    
    119.          String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/").toString();   
    120.          logger.info("tempContextUrl - {}", tempContextUrl);  
    121.            
    122.          String key_id = UuidUtil.generateShortUuid();  
    123.          QRCode qRCode = new QRCode();  
    124.          qRCode.setAndroid_url(android_url);  
    125.          qRCode.setIos_url(ios_url);  
    126.          qRCode.setKey_id(key_id);  
    127.          int intInsert = qRCodeService.insert(qRCode);  
    128.            
    129.          String path = request.getSession().getServletContext().getRealPath("upload");  
    130.          String fileName = new Date().getTime() + "qrcode.png";  
    131.          File createFile = new File(path+"/"+fileName);  
    132.            
    133.          //访问路径 服务器地址+ findAppUrl + key_id  
    134.          String urltxt = tempContextUrl+"findAppUrl/"+key_id;  
    135.          logger.info("urltxt - {}", urltxt);  
    136.            
    137.          //生成二维码  
    138.          String imageBase64QRCode = "";  
    139.          if(logoFile != null){  
    140.              String logoFileName = logoFile.getOriginalFilename();  
    141.              File targetFile = new File(path, logoFileName);    
    142.              if(!targetFile.exists()){    
    143.                  targetFile.mkdirs();    
    144.              }   
    145.              logoFile.transferTo(targetFile);  
    146.              imageBase64QRCode = ZXingCodeUtil.getLogoQRCode(urltxt, request, "", targetFile, createFile);  
    147.              //删除上传的logo  
    148.              targetFile.delete();  
    149.          }else{  
    150.              imageBase64QRCode = ZXingCodeUtil.getQRCode(urltxt, request, "", createFile);  
    151.          }  
    152.            
    153.          //二维码地址  
    154.          String qrcode_path = tempContextUrl+"upload/"+fileName;  
    155.            
    156.          JsonResult jsonResult = new JsonResult();  
    157.          Map data = new HashMap<String, String>();  
    158.          data.put("recreateFlag""0");  
    159.          data.put("qrcode_path", qrcode_path);  
    160.          data.put("accessKey""13598992");  
    161.          data.put("shortUrl", urltxt);  
    162.          jsonResult.setData(data);  
    163.          jsonResult.setMeg("生成成功");  
    164.          jsonResult.setRes(1);  
    165.        
    166.         return jsonResult;   
    167.     }  
    168.       
    169.     /** 
    170.      * url链接或者文本生成二维码 
    171.      * @param request 
    172.      * @param model 
    173.      * @return 
    174.      * @throws IOException 
    175.      */  
    176.     @RequestMapping("urlQRCode")  
    177.     @ResponseBody  
    178.     public JsonResult  UrlQRCode(HttpServletRequest request,ModelMap model,  
    179.             @RequestParam(value="file",required=false) CommonsMultipartFile logoFile,  
    180.             @RequestParam(value="urltxt",required=false) String urltxt) throws IOException {  
    181.           
    182.          logger.info("UrlQRCode - {}""开始了");  
    183.          logger.info("页面传递的文本内容- {}", urltxt);  
    184.            
    185.          StringBuffer url = request.getRequestURL();    
    186.          String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/").toString();   
    187.            
    188.            
    189.          String path = request.getSession().getServletContext().getRealPath("upload");  
    190.          String fileName = new Date().getTime() + "url.png";  
    191.          File createFile = new File(path+"/"+fileName);  
    192.          //生成二维码  
    193.          String imageBase64QRCode = "";  
    194.          if(logoFile != null){  
    195.              String logoFileName = logoFile.getOriginalFilename();  
    196.              File targetFile = new File(path, logoFileName);    
    197.              if(!targetFile.exists()){    
    198.                  targetFile.mkdirs();    
    199.              }   
    200.              logoFile.transferTo(targetFile);  
    201.              imageBase64QRCode = ZXingCodeUtil.getLogoQRCode(urltxt, request, "", targetFile, createFile);  
    202.              //删除上传的logo  
    203.              targetFile.delete();  
    204.          }else{  
    205.              imageBase64QRCode = ZXingCodeUtil.getQRCode(urltxt, request, "", createFile);  
    206.          }  
    207.            
    208.          //二维码地址  
    209.          String qrcode_path = tempContextUrl+"upload/"+fileName;  
    210.            
    211.          JsonResult jsonResult = new JsonResult();  
    212.          Map data = new HashMap<String, String>();  
    213.          data.put("qrcode_path", qrcode_path);  
    214.          data.put("qrcode", imageBase64QRCode);  
    215.          jsonResult.setData(data);  
    216.          jsonResult.setMeg("生成成功");  
    217.          jsonResult.setRes(1);  
    218.        
    219.         return jsonResult;   
    220.     }  
    221.       
    222.     /** 
    223.      * 二维码下载 
    224.      * @param qrcode_path 
    225.      * @param request 
    226.      * @param response 
    227.      * @throws IOException 
    228.      */  
    229.     @RequestMapping("/download")    
    230.     public void downloadFile(@RequestParam(value="qrcode_path",required=true) String qrcode_path,  
    231.             HttpServletRequest request, HttpServletResponse response) throws IOException {      
    232.           
    233.         String destUrl = qrcode_path;  
    234.         // 建立链接      
    235.         URL url = new URL(destUrl);      
    236.         HttpURLConnection httpUrl = (HttpURLConnection) url.openConnection();      
    237.         // 连接指定的资源      
    238.         httpUrl.connect();      
    239.         // 获取网络输入流      
    240.         BufferedInputStream bis = new BufferedInputStream(httpUrl.getInputStream());      
    241.         
    242.         response.setContentType("application/x-msdownload");      
    243.         response.setHeader("Content-Disposition""attachment; filename="+java.net.URLEncoder.encode(new Date().getTime()+"url.png","UTF-8"));      
    244.         OutputStream out = response.getOutputStream();      
    245.         byte[] buf = new byte[1024];      
    246.         if (destUrl != null) {      
    247.             BufferedInputStream br = bis;      
    248.             int len = 0;      
    249.             while ((len = br.read(buf)) > 0){      
    250.                 out.write(buf, 0, len);      
    251.             }                     
    252.             br.close();      
    253.         }      
    254.         out.flush();      
    255.         out.close();      
    256.     }   
    257.       
    258.       
    259.     /** 
    260.      * 二维码解析 
    261.      * @param request 
    262.      * @param model 
    263.      * @return 
    264.      * @throws IOException 
    265.      */  
    266.     @RequestMapping("parseQRCode")  
    267.     @ResponseBody  
    268.     public JsonResult  ParseQRCode(HttpServletRequest request,ModelMap model,  
    269.             @RequestParam(value="file",required=false) CommonsMultipartFile logoFile) throws IOException {  
    270.           
    271.          logger.info("ParseQRCode - {}""开始了");  
    272.            
    273.          StringBuffer url = request.getRequestURL();    
    274.          String tempContextUrl = url.delete(url.length() - request.getRequestURI().length(), url.length()).append(request.getContextPath()).append("/").toString();   
    275.           
    276.          String path = request.getSession().getServletContext().getRealPath("upload");  
    277.            
    278.          String logoFileName = logoFile.getOriginalFilename();  
    279.          File targetFile = new File(path, logoFileName);    
    280.          if(!targetFile.exists()){    
    281.              targetFile.mkdirs();    
    282.          }   
    283.          logoFile.transferTo(targetFile);  
    284.            
    285.          String text = ZXingCodeUtil.parseQRCode(targetFile);  
    286.            
    287.          targetFile.delete();  
    288.            
    289.          logger.info("解析结果 - {}", text);  
    290.            
    291.          JsonResult jsonResult = new JsonResult();  
    292.          Map data = new HashMap<String, String>();  
    293.          data.put("text", text);  
    294.          jsonResult.setData(data);  
    295.          jsonResult.setMeg("生成成功");  
    296.          jsonResult.setRes(1);  
    297.        
    298.         return jsonResult;   
    299.     }  
    300. }   
    展开全文
  • 条形码/二维码之开源利器ZXing图文介绍 [url]http://sjsky.iteye.com/blog/1142177[/url] java二维码工具类,中间带LOGO的,很强大 <groupId>com.google.zxing</groupId> <artifactId>core <version>3.2.0...
    图片输出到客户端:
    
            BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    ......
    resp.setHeader("Pragma", "no-cache");
    resp.setHeader("Cache-Control", "no-cache");
    resp.setDateHeader("Expires", 0);

    resp.setContentType("image/jpeg");

    ServletOutputStream sos = resp.getOutputStream();
    ImageIO.write(buffImg, "jpeg", sos);
    sos.close();



    条形码/二维码之开源利器ZXing图文介绍 [url]http://sjsky.iteye.com/blog/1142177[/url]
    java二维码工具类,中间带LOGO的,很强大

            <dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.2.0</version>
    </dependency>
    <dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.2.0</version>
    </dependency>


    [url]http://blog.csdn.net/mmm333zzz/article/details/17259513[/url]
    package com.util.cccm;  

    import java.awt.BasicStroke;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.Shape;
    import java.awt.geom.RoundRectangle2D;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.OutputStream;
    import java.util.Hashtable;
    import java.util.Random;

    import javax.imageio.ImageIO;

    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.DecodeHintType;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.Result;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

    /**
    * 二维码工具类
    *
    */
    public class QRCodeUtil {

    private static final String CHARSET = "utf-8";
    private static final String FORMAT_NAME = "JPG";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;
    // LOGO宽度
    private static final int WIDTH = 60;
    // LOGO高度
    private static final int HEIGHT = 60;

    private static BufferedImage createImage(String content, String imgPath,
    boolean needCompress) throws Exception {
    Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
    hints.put(EncodeHintType.MARGIN, 1);
    BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
    BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
    int width = bitMatrix.getWidth();
    int height = bitMatrix.getHeight();
    BufferedImage image = new BufferedImage(width, height,
    BufferedImage.TYPE_INT_RGB);
    for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
    image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
    : 0xFFFFFFFF);
    }
    }
    if (imgPath == null || "".equals(imgPath)) {
    return image;
    }
    // 插入图片
    QRCodeUtil.insertImage(image, imgPath, needCompress);
    return image;
    }

    /**
    * 插入LOGO
    *
    * @param source
    * 二维码图片
    * @param imgPath
    * LOGO图片地址
    * @param needCompress
    * 是否压缩
    * @throws Exception
    */
    private static void insertImage(BufferedImage source, String imgPath,
    boolean needCompress) throws Exception {
    File file = new File(imgPath);
    if (!file.exists()) {
    System.err.println(""+imgPath+" 该文件不存在!");
    return;
    }
    Image src = ImageIO.read(new File(imgPath));
    int width = src.getWidth(null);
    int height = src.getHeight(null);
    if (needCompress) { // 压缩LOGO
    if (width > WIDTH) {
    width = WIDTH;
    }
    if (height > HEIGHT) {
    height = HEIGHT;
    }
    Image image = src.getScaledInstance(width, height,
    Image.SCALE_SMOOTH);
    BufferedImage tag = new BufferedImage(width, height,
    BufferedImage.TYPE_INT_RGB);
    Graphics g = tag.getGraphics();
    g.drawImage(image, 0, 0, null); // 绘制缩小后的图
    g.dispose();
    src = image;
    }
    // 插入LOGO
    Graphics2D graph = source.createGraphics();
    int x = (QRCODE_SIZE - width) / 2;
    int y = (QRCODE_SIZE - height) / 2;
    graph.drawImage(src, x, y, width, height, null);
    Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
    graph.setStroke(new BasicStroke(3f));
    graph.draw(shape);
    graph.dispose();
    }

    /**
    * 生成二维码(内嵌LOGO)
    *
    * @param content
    * 内容
    * @param imgPath
    * LOGO地址
    * @param destPath
    * 存放目录
    * @param needCompress
    * 是否压缩LOGO
    * @throws Exception
    */
    public static void encode(String content, String imgPath, String destPath,
    boolean needCompress) throws Exception {
    BufferedImage image = QRCodeUtil.createImage(content, imgPath,
    needCompress);
    mkdirs(destPath);
    String file = new Random().nextInt(99999999)+".jpg";
    ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
    }

    /**
    * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
    * @author lanyuan
    * Email: mmm333zzz520@163.com
    * @date 2013-12-11 上午10:16:36
    * @param destPath 存放目录
    */
    public static void mkdirs(String destPath) {
    File file =new File(destPath);
    //当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
    if (!file.exists() && !file.isDirectory()) {
    file.mkdirs();
    }
    }

    /**
    * 生成二维码(内嵌LOGO)
    *
    * @param content
    * 内容
    * @param imgPath
    * LOGO地址
    * @param destPath
    * 存储地址
    * @throws Exception
    */
    public static void encode(String content, String imgPath, String destPath)
    throws Exception {
    QRCodeUtil.encode(content, imgPath, destPath, false);
    }

    /**
    * 生成二维码
    *
    * @param content
    * 内容
    * @param destPath
    * 存储地址
    * @param needCompress
    * 是否压缩LOGO
    * @throws Exception
    */
    public static void encode(String content, String destPath,
    boolean needCompress) throws Exception {
    QRCodeUtil.encode(content, null, destPath, needCompress);
    }

    /**
    * 生成二维码
    *
    * @param content
    * 内容
    * @param destPath
    * 存储地址
    * @throws Exception
    */
    public static void encode(String content, String destPath) throws Exception {
    QRCodeUtil.encode(content, null, destPath, false);
    }

    /**
    * 生成二维码(内嵌LOGO)
    *
    * @param content
    * 内容
    * @param imgPath
    * LOGO地址
    * @param output
    * 输出流
    * @param needCompress
    * 是否压缩LOGO
    * @throws Exception
    */
    public static void encode(String content, String imgPath,
    OutputStream output, boolean needCompress) throws Exception {
    BufferedImage image = QRCodeUtil.createImage(content, imgPath,
    needCompress);
    ImageIO.write(image, FORMAT_NAME, output);
    }

    /**
    * 生成二维码
    *
    * @param content
    * 内容
    * @param output
    * 输出流
    * @throws Exception
    */
    public static void encode(String content, OutputStream output)
    throws Exception {
    QRCodeUtil.encode(content, null, output, false);
    }

    /**
    * 解析二维码
    *
    * @param file
    * 二维码图片
    * @return
    * @throws Exception
    */
    public static String decode(File file) throws Exception {
    BufferedImage image;
    image = ImageIO.read(file);
    if (image == null) {
    return null;
    }
    BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(
    image);
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
    Result result;
    Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
    hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
    result = new MultiFormatReader().decode(bitmap, hints);
    String resultStr = result.getText();
    return resultStr;
    }

    /**
    * 解析二维码
    *
    * @param path
    * 二维码图片地址
    * @return
    * @throws Exception
    */
    public static String decode(String path) throws Exception {
    return QRCodeUtil.decode(new File(path));
    }

    public static void main(String[] args) throws Exception {
    String text = "薯 灯可分列式本上楞珂要瓜熟蒂落!000000000000000";
    QRCodeUtil.encode(text, "c:/df.jsp", "c:/a/", true);
    }
    }
    展开全文
  • iOS开发扫描二维码

    2017-12-13 11:48:42
    自iOS7以后,iOS扫描二维码不需要借助于第三方框架了,苹果在AVFoundation中原生支持了扫描二维码的API,主要涉及到5个类,这5个类在自定义相机或者视频时也用得上,网上有很多介绍,这5个类分别为: ...

    自iOS7以后,iOS扫描二维码不需要借助于第三方框架了,苹果在AVFoundation中原生支持了扫描二维码的API,主要涉及到5个类,这5个类在自定义相机或者视频时也用得上,网上有很多介绍,这5个类分别为:

    AVCaptureSession:媒体捕获会话,负责把捕获的音视频数据输出到输出设备中。
    
    AVCaptureDevice:输入设备,如麦克风、摄像头。
    
    AVCaptureDeviceInput:设备输入数据管理对象,可以根据AVCaptureDevice创建对应的AVCaptureDeviceInput对象,该对象将会被添加到AVCaptureSession中管理。
    
    AVCaptureOutput:输出数据管理对象,用于接收各类输出数据,有很多子类,每个子类用途都不一样,该对象将会被添加到AVCaptureSession中管理。
    
    AVCaptureVideoPreviewLayer:相机拍摄预览图层,是CALayer的子类,使用该对象可以实时查看拍照或视频录制效果,设置好尺寸后需要添加到父view的layer中。
    复制代码

    我在参考了网上的很多博客并自己摸索了以后,写了一个具体的实现案例,过程中遇到很多坑,在此记录并分享一下。

    运行环境:Xcode 8.3.2 + iOS 8. 4真机、iOS 10.3.1真机

    一、核心步骤:

    1、创建AVCaptureSession会话 2、创建AVCaptureDevice设备 3、创建输入AVCaptureDeviceInput与输出设备AVCaptureMetadataOutput,并添加到上面的会话中 4、创建预览层 5、设置扫描区域

    二、实现

    从上面的描述看,除了预览层,其他的和UI界面似乎没什么关系,但是实际开发中,扫描界面一般都是设计的比较人性化的,如支付宝、微信等,中间都有一个小框,有个线上下扫,这个其实就是用UI来配合扫描二维码,给用户一种好的体验。

    1、界面布局

    2、主要代码

    #import "ViewController.h"
    #import <AVFoundation/AVFoundation.h>
    
    @interface ViewController () <AVCaptureMetadataOutputObjectsDelegate, CALayerDelegate>
    
    /**
     *  UI
     */
    @property (weak, nonatomic) IBOutlet UIView *scanView;
    @property (weak, nonatomic) IBOutlet UIImageView *scanline;
    @property (weak, nonatomic) IBOutlet UILabel *result;
    
    /**
     *  扫描区域的高度约束值(宽度一致)
     */
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *scanViewH;
    /**
     *  扫描线的顶部约束值
     */
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *scanlineTop;
    /**
     *  扫描线的高度
     */
    @property (weak, nonatomic) IBOutlet NSLayoutConstraint *scanlineH;
    @property(nonatomic, strong) CALayer *maskLayer;
    
    /**
     *  五个类
     */
    @property(nonatomic, strong) AVCaptureDevice *device;
    
    @property(nonatomic, strong)  AVCaptureDeviceInput *input;
    
    @property(nonatomic, strong)  AVCaptureMetadataOutput *output;
    
    @property(nonatomic, strong) AVCaptureSession *session;
    
    @property(nonatomic, strong) AVCaptureVideoPreviewLayer *layer;
    
    @end
    
    @implementation ViewController
    
    #pragma mark - 懒加载
    
    -(AVCaptureDevice *)device{
        if (_device == nil) {
            
            _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
            
        }
        return _device;
        
    }
    
    -(AVCaptureDeviceInput *)input{
        
        if (_input == nil) {
            
            _input = [AVCaptureDeviceInput deviceInputWithDevice:self.device error:nil];
            
        }
        
        return  _input;
        
    }
    
    -(AVCaptureMetadataOutput *)output{
        
        if (_output == nil) {
            
            _output = [[AVCaptureMetadataOutput alloc]init];
            
            [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
            
        }
        
        return  _output;
    }
    
    #pragma mark - ViewController生命周期
    /**
     *  执行扫描动画
     */
    -(void)viewDidAppear:(BOOL)animated{
        
        [super viewDidAppear:animated];
        
        [self startAnim];
        
    }
    
    /**
     *  注册进入前台通知 保证下次进来还有扫描动画
     */
    -(void)viewWillAppear:(BOOL)animated{
        
        [super viewWillAppear:animated];
    
        //注册程序进入前台通知
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (startAnim) name: UIApplicationWillEnterForegroundNotification object:nil];
    }
    
    /**
     *  移除通知
     */
    -(void)viewWillDisappear:(BOOL)animated{
        
        [super viewWillDisappear:animated];
        //解除程序进入前台通知
        [[NSNotificationCenter defaultCenter] removeObserver:self name: UIApplicationWillEnterForegroundNotification object:nil];
         
         
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        
        //1、创建会话
        AVCaptureSession *session = [[AVCaptureSession alloc]init];
        
        if ([session canSetSessionPreset:AVCaptureSessionPresetHigh]) {
            
            [session setSessionPreset:AVCaptureSessionPresetHigh];
            
        }
        
        //2、添加输入和输出设备
        if([session canAddInput:self.input]){
            
            [session addInput:self.input];
            
        }
        if([session canAddOutput:self.output]){
            
            [session addOutput:self.output];
        }
        
        
        //3、设置这次扫描的数据类型
        self.output.metadataObjectTypes = self.output.availableMetadataObjectTypes;
        
        //4、创建预览层
        AVCaptureVideoPreviewLayer *layer = [AVCaptureVideoPreviewLayer layerWithSession:session];
        
        layer.frame = self.view.bounds;
        
        [self.view.layer insertSublayer:layer atIndex:0];
        
        
        //5、创建周围的遮罩层
        CALayer *maskLayer = [[CALayer alloc]init];
        
        maskLayer.frame = self.view.bounds;
        
        //此时设置的颜色就是中间扫描区域最终的颜色
        maskLayer.backgroundColor = [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.2].CGColor;
        
        maskLayer.delegate = self;
        
        [self.view.layer insertSublayer:maskLayer above:layer];
        
        //让代理方法调用 将周围的蒙版颜色加深
        [maskLayer setNeedsDisplay];
        
        
        //6、关键设置扫描的区域 方法一:自己计算
        //    CGFloat x = (self.view.bounds.size.width - self.scanViewH.constant) * 0.5;
        //
        //    CGFloat y = (self.view.bounds.size.height- self.scanViewH.constant) * 0.5;
        //
        //    CGFloat w = self.scanViewH.constant;
        //
        //    CGFloat h = w;
        //
        //
        //    self.output.rectOfInterest = CGRectMake(y/self.view.bounds.size.height, x/self.view.bounds.size.width,  h/self.view.bounds.size.height, w/self.view.bounds.size.width);
        
        //6、关键设置扫描的区域,方法二:直接转换,但是要在 AVCaptureInputPortFormatDescriptionDidChangeNotification 通知里设置,否则 metadataOutputRectOfInterestForRect: 转换方法会返回 (0, 0, 0, 0)。
        
        __weak __typeof(&*self)weakSelf = self;
        
        [[NSNotificationCenter defaultCenter] addObserverForName:AVCaptureInputPortFormatDescriptionDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock: ^(NSNotification *_Nonnull note) {
            
            weakSelf.output.rectOfInterest = [weakSelf.layer metadataOutputRectOfInterestForRect:self.scanView.frame];
            
        }];
        
        
        //7、开始扫描
        [session startRunning];
        
        
        self.session = session;
        self.layer = layer;
        self.maskLayer = maskLayer;
    }
    
    -(void)dealloc{
        
        [[NSNotificationCenter defaultCenter] removeObserver:self];
        
    }
    
    
    #pragma mark - 代理方法
    /**
     *  如果扫描到了二维码 回调该代理方法
     */
    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection{
        
        if(metadataObjects.count > 0 && metadataObjects != nil){
            
            
            AVMetadataMachineReadableCodeObject *metadataObject = [metadataObjects lastObject];
            
            NSString *result = metadataObject.stringValue;
            
            self.result.text = result;
            
            [self.session stopRunning];
            
            [self.scanline removeFromSuperview];
            
        }
        
        
    }
    
    /**
     *   蒙版中间一块要空出来
     */
    
    -(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
        
        if (layer == self.maskLayer) {
            
            UIGraphicsBeginImageContextWithOptions(self.maskLayer.frame.size, NO, 1.0);
            
            //蒙版新颜色
            CGContextSetFillColorWithColor(ctx, [UIColor colorWithRed:0.1 green:0.1 blue:0.1 alpha:0.8].CGColor);
            
            CGContextFillRect(ctx, self.maskLayer.frame);
            
            //转换坐标
            CGRect scanFrame = [self.view convertRect:self.scanView.frame fromView:self.scanView.superview];
            
            //空出中间一块
            CGContextClearRect(ctx, scanFrame);
        }
    }
    
    @end
    
    #pragma mark - 自定义方法
    /**
     *  扫描的那条线动起来
     */
    -(void)startAnim{
        
        //如果是第二次进来 那么动画已经执行完毕 要重新开始动画的话 必须让约束归位
        if(self.scanlineTop.constant == self.scanViewH.constant - 4){
        
            self.scanlineTop.constant -= self.scanViewH.constant - 4;
        
            [self.view layoutIfNeeded];
        
        }
        
        //执行动画
        [UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionRepeat animations:^{
    
            self.scanlineTop.constant = self.scanViewH.constant - 4;
            
            [self.view layoutIfNeeded];
            
            
        } completion:nil];
        
    }
    复制代码

    Info.plist中 不同iOS版本需要添加相应的权限

    三、最终效果

    总结

    一、遇到的坑

    1、设置了AutoLayout,想要做动画,这时候动画放在viewDidAppear中执行,并且不要用bounds,frame来改变动画,要用具体的约束,但是直接在UIView动画中修改约束是没效果的,需要在设置完约束以后,加上[self.view layoutIfNeeded];

    2、设置扫描区域,也就是设置AVCaptureMetadataOutputrectOfInterest属性,它是一个CGRect类型,但是它的四个值和传统的不一样,是**(y,x,高,宽)**且是比例值,取值范围为0~1。那么有两种方案,第一种需要自己计算具体位置的比例,如代码中注释的那些。第二种方案用AVCaptureVideoPreviewLayermetadataOutputRectOfInterestForRect方法,但是直接设置是没有效果的,必须放到通知里,如文中所示。

    3、中间方块是通过CALayer两步实现的,第一步设置整个背景颜色,这个颜色根据中间想显示的样式来设置;第二步在代理方法里面重新设置一次背景颜色,这个颜色根据除中间以外的区域来设置,然后将中间的挖掉。但是必须调用setNeedsDisplay方法,否则代理方法不会调用。

    二、参考文献

    1、iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
    2、iOS开发 - 二维码的扫描
    3、iOS二维码扫描与生成(优化启动卡顿)

    三、源代码

    转载于:https://juejin.im/post/5a31139a51882560e356a2f8

    展开全文
  • 二维码生成

    2019-07-11 16:08:39
    -- 二维码 --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.0</version> </dependency...
  • 神奇的二维码

    千次阅读 2018-10-26 14:23:58
    以前看到二维码,总觉得这是一个神奇的东西,也没有去深入的了解过,最近一个偶然的机会接触到了二维码,真实的体会了它的奥妙处,然后就从中汲取了一些养分与大家分享,希望对大家有用,代码如下: 工具类(Util...
  • Java实现二维码

    2017-02-08 16:35:36
    今天这篇博客,主要是利用Java实现二维码: 在写代码之前先讲一下整体思路,以方便更好更快捷的实现功能。 (1).首先要想实现二维码功能需要导入com.google.zxing的核心jar包,我这里导入的是core-3.2.1.jar; (2)....
  • 2.二维码生成及结合FastDFS文件服务器储存Utils package com.ytkj.teammanager.common.utils; import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.*...
  • python之父实名反对996

    2019-04-26 08:07:58
    python之父实名反对996 在互联网公司之中,实行“996 工作制”几乎成为默认标配,在去年的年会中,有赞 CEO 白鸦将这种企业文化公开的在公司年会提出、并被广泛地传播出来,撕掉了互联网企业因焦虑而追赶的遮羞布...
  • 项目中本来已使用Zxing来实现二维码功能,但是在ZXing的识别效率太低,以至于在某些极端情况下,识别效果实在无法忍受,这不一定是算法问题,应该很大原因在于Zxing使用java实现。没办法只能尝试使用ZBar开源库,这...
  • 计算机视觉研究院专栏作者:Edison_G不要对 Python 4.0 抱有希望,可能不会有的。——Python 之父 Guido van Rossum长按扫描二维码关注我们转自机器之心2...
  • 关键点在于如何从图像中快速而准确的找到二维码区域,寻找到二维码三个匹配模式点(定位块)。 一:二维码的组成 要关注的是图中三个黑色正方形区域,它们就是用来定位一个二维码的最重要的三个区域,首先要做的...
  • 这位科学大牛一生中顶着各种“XX之父”的头衔, 首先提出了现代计算机的理论模型, 用有限状态机来描述一个可以自我学习的机器。 今天我来给大家科普一个技术领域中的英雄,就是本文的主人公阿兰·图灵,先来给大家...
  • 90年代,大多数人还不知互联网为何物的时候,28岁的张小龙就单凭一人力,开发了当时国内最好用的邮箱-Foxmail。一举成名天下知。不仅结识了雷军、周鸿祎、马化腾等大佬。他也成为全国程序员膜拜的对象,位列国内...
  • Python 之父 Guido van Rossum 在推特公布了自己从 Dropbox 公司离职的消息,并表示已经退休。他还提到自己在 Dropbox 担任工程师期间学...
  • Python 之父抛弃 Python!

    千次阅读 2018-07-13 17:05:41
    昨天,Python 之父 Guido van Rossum 在 Python 邮件组里发邮称,他将退出 Python 核心决策层,而转居幕后。▌Python 被抛弃?从 ...
  • opencv库识别QR二维码-QT

    万次阅读 2021-01-16 01:28:59
    使用opencv库识别QR二维码,框出图片中的二维码,并使用开源库Zxing解码,在这过程中学习理解opencv库相应的函数。 环境: 1. window7系统 2. QT create 1.准备 首先安装QT和QT create开发环境,window下使用...
  • 第一步:准备依赖包:core-3.0.0.jar (扫二维码下载依赖包,哈哈)和一张准备放在二维码中间的图片 下载地址:http://central.maven.org/maven2/com/google/zxing/core/3.0.0/ 第二步:打开Eclipse,新建一个web...
  • 别了!Python之父

    2018-12-10 20:52:51
    前段时间,Python之父退出了Python,这个创造出了世界上最令人欢迎的编程语言之一Python(胶水语言)的技术界大牛终于不用再为运营的事情苦恼了!有人说:耿直的技...
  • 被称为“微信之父”的张小龙,目前是年薪近3亿的腾讯副总裁,而他本人却有着与身份并不相称的低调。“我不需要,我不需要华彩的生活。” 不过,一贯低调的他昨天却刷屏了体育频道。 在刚刚结束的欧巡赛-...
  • 在网站开发中,经常会遇到要生成二维码的情况,比如要使用微信支付、网页登录等,本文分享一个Spring Boot生成二维码的例子,这里用到了google的zxing工具类。...
  • ArcBlock Technical Learning Series 第十七期进击的二维码本周三,1 月 30 日下午 1:30 时 (美国太平洋时间 29日下午 21:30 时),由 ArcBloc 后端工程师孙博山 授课。复制代码二维码源于日本,如今世界各国都在...
  • 微信小程序 带参二维码 纯Java实现

    千次阅读 多人点赞 2020-05-25 17:25:27
    微信小程序中一物一码的实现,当用户使用微信扫描该二维码,会自动跳转到指定的小程序,并传入指定的参数......
  • Opencv的使用小教程3——利用轮廓检测实现二维码定位二维码具有什么特征识别二维码的流程1、预处理图像2、寻找轮廓 好好学习噢! 二维码具有什么特征 二维码就是两个维度的条形码,平常我们在生活中随处可见,“QR...
  • “ 阅读本文大概需要 1 分钟。 ”就昨天的时候,Python 之父 Guido 发了个推特,说自己觉得退休太无聊了,然后于是乎决定加入微软。同时推特上大神 Anders Hejlsbe...
  • 前言 因工作需要,需要定位图片中的二维码;我遂查阅了相关资料,也学习了opencv开源库。通过一番努力,终于很好的实现了二维码定位。本文将讲解如何使用opencv定位二维码。...二维码在设计初就考虑到了识...
  • Guido van Rossum,Python之父,就是他用一部英国喜剧《蒙提·派森的飞行马戏团》(Monty Python and the Flying Circus)命名了这门语言。1989年,他在荷兰创造了Python(果然名字里有Van的都是荷兰人吗); 1991年...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,826
精华内容 2,730
关键字:

二维码之父