在线二维码生成器
输入文字即时输入即时生成!提示:建议内容不超过150个字符,使低配置手机也能扫描到结果。如果内容超过150个字符,请使用活码系统!输入URL网址即时输入即时生成!如果你的网址过长,生成的二维码图片将不易被扫描推荐使用活码系统,支持多网址,可实现后台链接调整
输入微博地址即时输入即时生成!地址请用http://或https://开头
输入邮箱地址即时输入即时生成!输入WiFi帐号信息即时输入即时生成!输入联系人信息即时输入即时生成!输入位置信息即时输入即时生成!请选择电脑上的文件即时输入即时生成!该功能必须登录才能使用二维码扫描出来的内容可以随时调整,帮您抓住商机。
如果内容有错误,可以随时修正,保护您的巨额营销费用和企业形象。
二维码图案不变,内容随时改。
甚至可以先把二维码印刷了贴出去,然后慢慢构想二维码的内容。
立即登录该功能必须登录才能使用帮助您利用移动互联网高效展示您的企业,推广您的产品。
立即登录免费二维码生成器
什么是二维码?二维码又称二维条码,常见的二维码为QRCode,QR全称QuickResponse,是一个近几年来移动设备上超流行的一种编码方式,它是一种比一维码更高级的条码格式,也能表示更多的数据类型,用某种特定的几何图形按一定规律在平面(二维方向上)分布的、黑白相间的、记录数据符号信息的图形;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理.
如何生成一个二维码?使用二维码生成器可以将网址,文本,WI-FI,位置,短信,电话号码,WhatsApp,Skype,Zoom,信用卡,Paypal,比特币等信息生成对应的二维码图片.
草料网址二维码生成器
网址静态码和网址跳转活码的区别网址静态码:
把输入的网址直接编码成为二维码,生成后无法修改网址,不能统计扫码量,适用于网址无需变更的情况。
网址跳转活码:
草料自动分配一个短网址用来跳转输入的目标网址,把这个短网址生成二维码,扫码后可以实时跳转到目标网址并记录访问数据。后期修改目标网址时,因并未改变短网址,所以二维码图案不变。
网址静态码
网址跳转活码
有效期
长期有效
长期有效
内容修改
内容固定,不支持修改
随时修改,二维码图案不变
批量生码
支持 生成批量静态码
不支持批量生码
数据统计
不支持数据统计
实时统计扫描数据
安全提示
无安全提示,直接访问
根据网站备案情况,展示安全提示页
二维码图案
网址链接越长,图案越复杂,不易识别
图案相对简单,容易扫码识别
关于数据统计:
不同于网址静态码,网址跳转活码可以实时统计二维码的扫描数据,同时支持数据导出。可前往【网址跳转活码】页面,点击对应跳转活码的【统计】按钮查看数据。
网址跳转活码扫码后为什么有提示页由于网址跳转活码生成后可随时修改网址,存在安全风险,网监部门与腾讯等平台要求加强网址跳转活码的审核力度,针对没有备案信息的网站,扫码后将显示安全提示页。了解详情
生成的网址码无法正常访问扫码过程只是对二维码进行解码,并跳转到对应的网址,跳转的页面内容取决于网址本身。页面访问异常可能是如下原因:
网址本身异常:扫码显示空白、错误等,可以将网址发送到微信聊天窗口,如果点击直接访问网址也失效,则证明该网址异常。网址本身被扫码平台限制访问:例如网址被投诉,微信会停止访问该网址。显示内容违规:无论免费版还是付费版,若活码内容违规,将被限制访问。查看详情显示内容被删除:活码被制作者删除,所以无法访问。如果你是制作者,可申请恢复。如何申请哪些网址在草料不能做所有需要特殊经营资质的内容和下载链接等(如棋牌类APP下载链接,支付链接等);未经icp备案,且内容可能存在风险,或者无法访问的网址链接;短网址链接;违反微信规则的相关链接;其他各种违反法律法规的链接,包括但不限于色情,博彩,欺诈等内容的网址链接。了解详情生成二维码、识别二维码的工具类
笔者日常:第一次用markdown写文章,有点手生~
声明:此工具类由本人二次整理改造后分享给大家,原编写者未知,虽然本人重写了大部分逻辑代码,但是核心部分仍然是采用的原来的代码。若涉及侵权问题,请随时联系笔者。
工具类使用示例:生成二维码:方式一:执行方法:/***生成二维码**@date2019/9/1010:39*/publicstaticStringtest1()throwsIOException,WriterException{returnQrCodeUtil.encodeQrCode("蚂蚁牙~嘿嘿",500,500,"C:\Users\JustryDeng\Desktop\abc\二维码(通过方式一生成).jpg");}生成效果如图:
方式二:执行方法:/***生成二维码**@date2019/9/1010:39*/publicstaticStringtest2()throwsIOException,WriterException{returnQrCodeUtil.encodeQrCodeAnotherWay("蚂蚁~~~",500,500,"C:\Users\JustryDeng\Desktop\abc\二维码(通过方式二生成).jpg");}生成效果如图:
生成带图片的二维码:执行方法:
/***生成带图片的二维码**@date2019/9/1010:39*/publicstaticStringtest3()throwsIOException,WriterException{returnQrCodeUtil.encodeQrCodeWithEmbeddedImg("我是二维码代表的数据内容",500,500,"C:\Users\JustryDeng\Desktop\1.png","C:\Users\JustryDeng\Desktop\abc\带图片的二维码.jpg");}生成效果如图:
生成带文字、带图片的二维码:执行方法:
/***生成带文字、带图片的二维码**@date2019/9/1010:39*/publicstaticStringtest4()throwsIOException,WriterException{QrImagepara=QrImage.builder().qrCodeFileOutputPath("C:\Users\JustryDeng\Desktop\abc\带文字带图片的二维码.jpg").qrCodeContent("http://www.baidu.com").qrCodeWidth(500).qrCodeHeight(500).embeddedImgFilePath("C:\Users\JustryDeng\Desktop\1.png").wordContent("我的二维码").wordSize(20).build();returnQrCodeUtil.encodeQrCodeWithEmbeddedImgAndFonts(para);}生成效果如图:
生成带文字、不带图片的二维码:执行方法:
/***生成带文字、不带图片的二维码**@date2019/9/1010:39*/publicstaticStringtest5()throwsIOException,WriterException{QrImagepara=QrImage.builder().qrCodeFileOutputPath("C:\Users\JustryDeng\Desktop\abc\带文字不带图片的二维码.jpg").qrCodeContent("二维码代表的数据内容~").qrCodeWidth(500).qrCodeHeight(500).wordContent("我是文字").wordSize(20).build();returnQrCodeUtil.encodeQrCodeWithEmbeddedImgAndFonts(para);}生成效果如图:
识别二维码:main方法:
被调用方法(两种方式均可):
/***识别二维码**@date2019/9/1010:39*/publicstaticStringtest6()throwsIOException,NotFoundException{returnQrCodeUtil.decodeQrCode(newFile("C:\Users\JustryDeng\Desktop\abc\二维码(通过方式一生成).jpg"));}/***识别二维码**@date2019/9/1010:39*/publicstaticStringtest7()throwsIOException,NotFoundException{returnQrCodeUtil.decodeQrCode(newFileInputStream("C:\Users\JustryDeng\Desktop\abc\带文字带图片的二维码.jpg"));}生成效果如图:
二维码工具类,使用示例完毕!
软硬件环境说明:Windows10、IntelliJIDEA、SpringBoot2.1.8.RELEASE。
生成二维码、识别二维码的工具类:相关核心依赖:com.google.zxingcore3.4.0com.google.zxingjavase3.4.0注:除了上述依赖外,本人还引入了lombok,完整的pom.xml是这样的:
4.0.0org.springframework.bootspring-boot-starter-parent2.1.8.RELEASEcom.szlaoziclzxing-demo0.0.1-SNAPSHOTzxing-demo使用zxing生成、识别二维码1.8org.springframework.bootspring-boot-starterorg.springframework.bootspring-boot-starter-testtestorg.projectlomboklomboktruecom.google.zxingcore3.4.0com.google.zxingjavase3.4.0org.springframework.bootspring-boot-maven-plugin相关模型:importlombok.*;/***二维码图片对象**@authorJustryDeng*@date2019/9/915:22*/@Data@Builder@NoArgsConstructor@AllArgsConstructorpublicclassQrImage{/**二维码的内容(非空)*/privateStringqrCodeContent;/**二维码的宽度(非空)*/privateIntegerqrCodeWidth;/**二维码的高度(非空)*/privateIntegerqrCodeHeight;/**二维码内嵌图片的文件路径(为空则表示:二维码中间不嵌套图片)*/privateStringembeddedImgFilePath;/**文字的大小(即:正方形文字的长度、宽度)(非空)*/privateIntegerwordSize;/**文字的内容(非空)*/privateStringwordContent;/**二维码文件的输出路径(非空)*/privateStringqrCodeFileOutputPath;}工具类:importcom.google.zxing.*;importcom.google.zxing.client.j2se.BufferedImageLuminanceSource;importcom.google.zxing.common.BitMatrix;importcom.google.zxing.common.HybridBinarizer;importcom.google.zxing.qrcode.decoder.ErrorCorrectionLevel;importcom.szlaozicl.zxingdemo.model.QrImage;importlombok.extern.slf4j.Slf4j;importjavax.imageio.ImageIO;importjava.awt.*;importjava.awt.geom.AffineTransform;importjava.awt.image.AffineTransformOp;importjava.awt.image.BufferedImage;importjava.io.*;importjava.nio.file.Path;importjava.util.HashMap;importjava.util.Map;/***二维码工具类**注:此工具类,是本人整理,但不是本人编写。*
*说明:二维码是一种编码形式,*将内容encode,得到二维码;,*将内容decode,得到数据内容。**@authorJustryDeng*@date2019/9/915:11*/@Slf4j@SuppressWarnings("unused")publicclassQrCodeUtil{/***嵌入的图片(被程序处理后)的高度(px)*
*注:内嵌图片不应占据遮挡二维码太多,否者可能导致生成的二维码无法识别。*建议内嵌图片的尺寸设置为二维码尺寸的1/5或1/4*/privatestaticintembeddedImgDefaultWidth;/**嵌入的图片(被程序处理后)的高度(px)*/privatestaticintembeddedImgDefaultHeight;/**嵌入的图片与二维码图片之间的框的宽度(px)*/privatestaticintframeWidth;/**嵌入的图片与二维码图片之间的框的颜色.*/privatestaticintframeWidthColor;/**二维码码的颜色*/privatestaticintqrCodeColor;/**二维码背景的颜色*/privatestaticintqrCodeBackgroundColor;/**图片缩小后,对那些"空"下的区域补色*/privatestaticintfillColor;/**二维码写码器*/privatestaticMultiFormatWritermultiFormatWriter=newMultiFormatWriter();/**初始化基本参数*/static{QrCodeUtil.embeddedImgDefaultWidth=80;QrCodeUtil.embeddedImgDefaultHeight=80;QrCodeUtil.frameWidth=0;QrCodeUtil.frameWidthColor=Color.BLUE.getRGB();QrCodeUtil.qrCodeColor=Color.BLACK.getRGB();QrCodeUtil.qrCodeBackgroundColor=Color.WHITE.getRGB();QrCodeUtil.fillColor=Color.RED.getRGB();}/***设置修改基本参数的参数值**@paramembeddedImgDefaultWidth*嵌入的图片(被程序处理后)的高度(px)*@paramembeddedImgDefaultHeight*嵌入的图片(被程序处理后)的高度(px)*@paramframeWidth*嵌入的图片与二维码图片之间的框的宽度(px)*@paramframeWidthColor*嵌入的图片与二维码图片之间的框的颜色*@paramqrCodeColor*二维码码的颜色*@paramqrCodeBackgroundColor*二维码背景的颜色*@paramfillColor*图片缩小后,对那些"空"下的区域补色*@date2019/9/922:47*/publicstaticvoidmodifyBasicParamsValues(IntegerembeddedImgDefaultWidth,IntegerembeddedImgDefaultHeight,IntegerframeWidth,ColorframeWidthColor,ColorqrCodeColor,ColorqrCodeBackgroundColor,ColorfillColor){if(embeddedImgDefaultWidth!=null){QrCodeUtil.embeddedImgDefaultWidth=embeddedImgDefaultWidth;}if(embeddedImgDefaultHeight!=null){QrCodeUtil.embeddedImgDefaultHeight=embeddedImgDefaultHeight;}if(frameWidth!=null){QrCodeUtil.frameWidth=frameWidth;}if(frameWidthColor!=null){QrCodeUtil.frameWidthColor=frameWidthColor.getRGB();}if(qrCodeColor!=null){QrCodeUtil.qrCodeColor=qrCodeColor.getRGB();}if(qrCodeBackgroundColor!=null){QrCodeUtil.qrCodeBackgroundColor=qrCodeBackgroundColor.getRGB();}if(fillColor!=null){QrCodeUtil.fillColor=fillColor.getRGB();}}/***生成二维码(到destImagePath指向的File)---方式一**@paramcontent*二维码的内容*@paramwidth*二维码的宽度(px)*@paramheight*二维码的高度(px)*@paramdestImagePath*生成二维码图片的地址**@return生成的二维码文件path*@throwsIOExceptionIOException*@throwsWriterExceptionWriterException**@date2019/9/916:43*/publicstaticStringencodeQrCode(Stringcontent,intwidth,intheight,StringdestImagePath)throwsIOException,WriterException{Filedest=getFile(destImagePath);//图像类型Stringformat="jpg";Maphints=newHashMap(4);hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");try(FileOutputStreamoutput=newFileOutputStream(dest)){//生成矩阵BitMatrixbitMatrix=newMultiFormatWriter().encode(content,BarcodeFormat.QR_CODE,width,height,hints);//输出图像MatrixToImageWriter.writeToStream(bitMatrix,format,output);}returndestImagePath;}/***生成二维码(到destImagePath指向的File)---方式二**@paramcontent*二维码的内容*@paramwidth*二维码的宽度(px)*@paramheight*二维码的高度(px)*@paramdestImagePath*生成二维码图片的地址**@return生成的二维码文件path*@throwsIOExceptionIOException*@throwsWriterExceptionWriterException**@date2019/9/916:43*/publicstaticStringencodeQrCodeAnotherWay(Stringcontent,intwidth,intheight,StringdestImagePath)throwsIOException,WriterException{booleanresult=ImageIO.write(genBufferedImage(content,width,height),"jpg",getFile(destImagePath));log.info("generateQrcodefile{}{}",destImagePath,result?"success":"fail");returndestImagePath;}/***生成带图片的二维码(到destImagePath指向的File)**@paramcontent*二维码的内容*@paramwidth*二维码的宽度(px)*@paramheight*二维码的高度(px)*@paramembeddedImgPath*被镶嵌的图片的地址*@paramdestImagePath*生成二维码图片的地址**@return生成的二维码文件path*@throwsIOExceptionIOException*@throwsWriterExceptionWriterException**@date2019/9/915:13*/publicstaticStringencodeQrCodeWithEmbeddedImg(Stringcontent,intwidth,intheight,StringembeddedImgPath,StringdestImagePath)throwsIOException,WriterException{booleanresult=ImageIO.write(genBufferedImageWithEmbeddedImg(content,width,height,embeddedImgPath),"jpg",getFile(destImagePath));log.info("generateQrcodefile{}{}",destImagePath,result?"success":"fail");returndestImagePath;}/***生成带图片的二维码(到outputStream流)**@paramcontent*二维码的内容*@paramwidth*二维码的宽度(px)*@paramheight*二维码的高度(px)*@paramembeddedImgPath*被镶嵌的图片的地址*注:被镶嵌的图片,如果尺寸**@throwsIOExceptionIOException*@throwsWriterExceptionWriterException**@date2019/9/916:43*/publicstaticvoidencodeQrCodeWithEmbeddedImg(Stringcontent,intwidth,intheight,StringembeddedImgPath,OutputStreamoutputStream)throwsIOException,WriterException{booleanresult=ImageIO.write(genBufferedImageWithEmbeddedImg(content,width,height,embeddedImgPath),"jpg",outputStream);log.info("generateQrcodefiletoOutputStream{}",result?"success":"fail");}/***生成上方带内嵌图片、带文字的二维码*
*注:若嵌入的图片的参数值为null或者为空的字符,那么只生成带文字的二维码**@paramparam*参数模型**@return生成的二维码文件path*@throwsIOExceptionIOException*@throwsWriterExceptionWriterException**@date2019/9/100:11*/publicstaticStringencodeQrCodeWithEmbeddedImgAndFonts(QrImageparam)throwsIOException,WriterException{//首先生成二维码图片BufferedImageqrImage;StringembeddedImgFilePath=param.getEmbeddedImgFilePath();StringqrCodeContent=param.getQrCodeContent();IntegerqrCodeWidth=param.getQrCodeWidth();IntegerqrCodeHeight=param.getQrCodeHeight();if(embeddedImgFilePath==null||embeddedImgFilePath.trim().length()==0){qrImage=genBufferedImage(qrCodeContent,qrCodeWidth,qrCodeHeight);}else{qrImage=genBufferedImageWithEmbeddedImg(qrCodeContent,qrCodeWidth,qrCodeHeight,embeddedImgFilePath);}intqrCodeImageWidth=qrImage.getWidth();intqrCodeImageHeight=qrImage.getHeight();String[]splitStrLines;splitStrLines=splitStrLines(param.getWordContent(),qrCodeImageWidth/param.getWordSize());//文字图片的高度=文字行数*每行高度(文字高度)+10px;//为了防止文字图片下面部分显示不全,特意在这里额外加10像素的高度。intfontsImageHeight=splitStrLines.length*param.getWordSize()+10;//创建顶部文字的图片BufferedImageimageWithFontsBufferedImage=newBufferedImage(qrCodeImageWidth,fontsImageHeight,BufferedImage.TYPE_4BYTE_ABGR);GraphicsfontsImageGraphics=imageWithFontsBufferedImage.getGraphics();fontsImageGraphics.fillRect(0,0,qrCodeImageWidth,fontsImageHeight);fontsImageGraphics.setColor(Color.black);fontsImageGraphics.setFont(newFont("宋体",Font.PLAIN,param.getWordSize()));//文字长度大于一行的长度,进行分行//每行限制的文字个数if(param.getWordContent().length()>qrCodeImageWidth/param.getWordSize()){for(inti=0;ifontsImageGraphics.drawString(param.getWordContent(),//总长度减去字长度除以2为向右偏移长度((qrCodeImageWidth/param.getWordSize()-param.getWordContent().length())/2)*param.getWordSize(),param.getWordSize());}//从图片中读取RGBint[]imageArrayFonts=newint[qrCodeImageWidth*fontsImageHeight];imageArrayFonts=imageWithFontsBufferedImage.getRGB(0,0,qrCodeImageWidth,fontsImageHeight,imageArrayFonts,0,qrCodeImageWidth);int[]imageArrayQr=newint[qrCodeImageWidth*qrCodeImageHeight];imageArrayQr=qrImage.getRGB(0,0,qrCodeImageWidth,qrCodeImageHeight,imageArrayQr,0,qrCodeImageWidth);//生成新图片(在setsetRGB时,通过控制图像的startX与startY,可达到不同的拼接效果)BufferedImagenewBufferedImage=newBufferedImage(qrCodeImageWidth,qrCodeImageHeight+fontsImageHeight,BufferedImage.TYPE_INT_RGB);//图片在上,文字在下//设置上半部分的RGBnewBufferedImage.setRGB(0,0,qrCodeImageWidth,qrCodeImageHeight,imageArrayQr,0,qrCodeImageWidth);//设置下半部分的RGBnewBufferedImage.setRGB(0,qrCodeImageHeight,qrCodeImageWidth,fontsImageHeight,imageArrayFonts,0,qrCodeImageWidth);//文字在上,图片在下////设置上半部分的RGB///newBufferedImage.setRGB(0,0,qrCodeImageWidth,fontsImageHeight,imageArrayFonts,0,qrCodeImageWidth);////设置下半部分的RGB///newBufferedImage.setRGB(0,fontsImageHeight,qrCodeImageWidth,qrCodeImageHeight,imageArrayQr,0,qrCodeImageWidth);StringqrCodeFileOutputPath=param.getQrCodeFileOutputPath();FileoutFile=getFile(qrCodeFileOutputPath);booleanresult=ImageIO.write(newBufferedImage,"jpg",outFile);log.info("generateQrcodefile{}{}",qrCodeFileOutputPath,result?"success":"fail");returnqrCodeFileOutputPath;}/***识别二维码内容信息**@paramfile二维码图片文件**@return二维码内容*@throwsNotFoundExceptionNotFoundException*@throwsIOExceptionIOException*@date2019/9/101:59*/publicstaticStringdecodeQrCode(Filefile)throwsNotFoundException,IOException{BufferedImageimage;image=ImageIO.read(file);if(image==null){returnnull;}Stringdata=decodeQrCode(image);log.info("Qrcodefrom[{}]datais->{}",file.getAbsolutePath(),data);returndata;}/***识别二维码内容信息**@paramis二维码图片文件流**@return二维码内容*@throwsNotFoundExceptionNotFoundException*@throwsIOExceptionIOException*@date2019/9/101:59*/publicstaticStringdecodeQrCode(InputStreamis)throwsNotFoundException,IOException{BufferedImageimage;image=ImageIO.read(is);if(image==null){returnnull;}Stringdata=decodeQrCode(image);log.info("QrcodefromInputStreamdatais->{}",data);returndata;}///--------------------------------------------------------以下为辅助方法、辅助类/***获取文件(顺带创建文件夹,如果需要的话)**@paramfilePath*文件path*@return文件对象*@date2019/9/1010:48*/privatestaticFilegetFile(StringfilePath){Filefile=newFile(filePath);if(!file.getParentFile().exists()){booleanresult=file.getParentFile().mkdirs();log.info("createdirectory{}{}",file.getParent(),result);}returnfile;}/***识别二维码内容信息**@paramimage二维码图片信息BufferedImage**@return二维码内容*@throwsNotFoundExceptionNotFoundException*@date2019/9/101:59*/privatestaticStringdecodeQrCode(BufferedImageimage)throwsNotFoundException{BufferedImageLuminanceSourcesource=newBufferedImageLuminanceSource(image);BinaryBitmapbitmap=newBinaryBitmap(newHybridBinarizer(source));Resultresult;HashMaphints=newHashMap(4);hints.put(DecodeHintType.CHARACTER_SET,"utf-8");result=newMultiFormatReader().decode(bitmap,hints);returnresult.getText();}/***生成二维码图片信息BufferedImage*
*注:BufferedImage即为二维码图片的数据容器,可以利用其进一步生成二维码图片**@paramcontent*二维码的数据内容*@paramwidth*二维码的宽(px)*@paramheight*二维码的高(px)**@return二维码图片信息BufferedImage*@throwsWriterExceptionWriterException*@date2019/9/916:39*/privatestaticBufferedImagegenBufferedImage(Stringcontent,intwidth,intheight)throwsWriterException{Maphints=getHints();//生成一个矩阵(即:生成一个二维数组)BitMatrixmatrix;matrix=multiFormatWriter.encode(content,BarcodeFormat.QR_CODE,width,height,hints);int[]pixels=newint[width*height];for(inty=0;y//控制二维码颜色,前面那个为二维码的颜色,后面那个为底色pixels[y*width+x]=matrix.get(x,y)?qrCodeColor:qrCodeBackgroundColor;}}BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);image.getRaster().setDataElements(0,0,width,height,pixels);returnimage;}/***生成(带内嵌图片的)二维码图片信息BufferedImage*
*注:BufferedImage即为二维码图片的数据容器,可以利用其进一步生成二维码图片**@paramcontent*二维码的数据内容*@paramwidth*二维码的宽(px)*@paramheight*二维码的高(px)*@paramembeddedImagePath*二维码中要嵌套的图片path**@return二维码图片信息BufferedImage*@throwsIOExceptionIOException*@throwsWriterExceptionWriterException*@date2019/9/916:39*/privatestaticBufferedImagegenBufferedImageWithEmbeddedImg(Stringcontent,intwidth,intheight,StringembeddedImagePath)throwsWriterException,IOException{//读取要嵌套的图像,并将其压缩到指定的宽高BufferedImagescaleImage=scale(embeddedImagePath,embeddedImgDefaultWidth,embeddedImgDefaultHeight,false);intembeddedImgFinalWidth=scaleImage.getWidth();intembeddedImgFinalHalfWidth=embeddedImgFinalWidth/2;intembeddedImgFinalHeight=scaleImage.getHeight();intembeddedImgFinalHalfHeight=embeddedImgFinalHeight/2;int[][]srcPixels=newint[embeddedImgFinalWidth][embeddedImgFinalHeight];for(inti=0;isrcPixels[i][j]=scaleImage.getRGB(i,j);}}Maphint=getHints();//生成一个矩阵(即:生成一个二维数组)(注:下面会在这个矩阵上绘图)BitMatrixmatrix=multiFormatWriter.encode(content,BarcodeFormat.QR_CODE,width,height,hint);//二维码矩阵转为一维像素数组intqrCodeHalfWidth=matrix.getWidth()/2;intqrCodeHalfHeight=matrix.getHeight()/2;int[]pixels=newint[width*height];//是否处于【嵌入图片与二维码图片之间的框】里booleanatEmbeddedImgFrameArea;//是否处于【嵌入图片的位置】里booleanatEmbeddedImgArea;//内嵌的图片(左下角)在二维码图片中的坐标XintembeddedImgCoordinatesX=qrCodeHalfWidth-embeddedImgFinalHalfWidth;//内嵌的图片(左下角)在二维码图片中的坐标YintembeddedImgCoordinatesY=qrCodeHalfHeight-embeddedImgFinalHalfHeight;for(inty=0;yatEmbeddedImgArea=x>qrCodeHalfWidth-embeddedImgFinalHalfWidth&&xqrCodeHalfHeight-embeddedImgFinalHalfHeight&&yqrCodeHalfWidth-embeddedImgFinalHalfWidth-frameWidth&&xqrCodeHalfHeight-embeddedImgFinalHalfHeight-frameWidth&&yqrCodeHalfWidth+embeddedImgFinalHalfWidth-frameWidth&&xqrCodeHalfHeight-embeddedImgFinalHalfHeight-frameWidth&&yqrCodeHalfWidth-embeddedImgFinalHalfWidth-frameWidth&&xqrCodeHalfHeight-embeddedImgFinalHalfHeight-frameWidth&&yqrCodeHalfWidth-embeddedImgFinalHalfWidth-frameWidth&&xqrCodeHalfHeight+embeddedImgFinalHalfHeight-frameWidth&&ypixels[y*width+x]=frameWidthColor;//二维码图片区域}else{//控制二维码颜色,前面那个为二维码的颜色,后面那个为底色pixels[y*width+x]=matrix.get(x,y)?qrCodeColor:qrCodeBackgroundColor;}}}BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);image.getRaster().setDataElements(0,0,width,height,pixels);returnimage;}/***获取hint信息**@returnhint*@date2019/9/101:14*/privatestaticMapgetHints(){Maphint=newHashMap(8);hint.put(EncodeHintType.CHARACTER_SET,"utf-8");hint.put(EncodeHintType.ERROR_CORRECTION,ErrorCorrectionLevel.H);//二维码整体白框hint.put(EncodeHintType.MARGIN,1);returnhint;}/***把传入的原始图像按高度(或宽度)进行缩小,生成符合要求的图标的BufferedImage信息*
*注:若图片原来的大小比给定的宽高小,那么不会进行放大,而是仍然保持原来的大小。**@paramsrcImageFile*源文件地址*@paramwidth*(缩小后的)宽度*@paramheight*(缩小后的)高度*@paramautoFill*是否对按比例缩小后的图片进行填充,使其完全达到给定的宽高。*
*注:图片按照最长边与对应的宽(或高)的比例缩小后,最长边缩小后的尺寸与给定的宽(或高)一致了,*但是其高(或宽),与缩小后的最短边不一定一样。此时,我们可以考虑使用给定的颜色对*其进行填充。如:想要嵌入进去的图片的实际宽是80,高是100;但是这里指定缩小后的尺寸为*宽为10,高为10。由下面的逻辑可知:缩小比例为0.1,缩小后,图片的宽就变成了8,高就变*成了10,此时高是满足我们的要求的,但是宽差了2个像素。此时就可以将其进行填充了。*
*注:建议为false。**@return图片的BufferedImage信息*@throwsIOExceptionIOException*@date2019/9/101:59*/privatestaticBufferedImagescale(StringsrcImageFile,intwidth,intheight,booleanautoFill)throwsIOException{//缩小比例doubleratio;Filefile=getFile(srcImageFile);BufferedImagesrcImage=ImageIO.read(file);ImagedestImage=srcImage.getScaledInstance(width,height,BufferedImage.SCALE_SMOOTH);//如果原图片的高或者宽大于指定的高或宽时,(以最长的一边来计算缩放比例,并)进行缩放if((srcImage.getHeight()>height)||(srcImage.getWidth()>width)){if(srcImage.getHeight()>srcImage.getWidth()){ratio=(newInteger(height)).doubleValue()/srcImage.getHeight();}else{ratio=(newInteger(width)).doubleValue()/srcImage.getWidth();}AffineTransformOpop=newAffineTransformOp(AffineTransform.getScaleInstance(ratio,ratio),null);destImage=op.filter(srcImage,null);}if(autoFill){BufferedImageimage=newBufferedImage(width,height,BufferedImage.TYPE_INT_RGB);Graphics2Dgraphic=image.createGraphics();graphic.setColor(Color.red);graphic.fillRect(0,0,width,height);if(width==destImage.getWidth(null)){graphic.drawImage(destImage,0,(height-destImage.getHeight(null))/2,destImage.getWidth(null),destImage.getHeight(null),Color.white,null);}else{graphic.drawImage(destImage,(width-destImage.getWidth(null))/2,0,destImage.getWidth(null),destImage.getHeight(null),Color.white,null);}graphic.dispose();destImage=image;}return(BufferedImage)destImage;}/***一行字符串拆分成多行*/privatestaticString[]splitStrLines(Stringstr,intlen){intblocks=str.length()/len+1;String[]strArray=newString[blocks];for(inti=0;istrArray[i]=str.substring(i*len);}else{strArray[i]=str.substring(i*len,(i+1)*len);}}returnstrArray;}/***Writesa{@linkBitMatrix}to{@linkBufferedImage},*fileorstream.Providedhereinsteadofcoresinceitdependson*JavaSElibraries.*/privatestaticclassMatrixToImageWriter{privatestaticfinalMatrixToImageConfigDEFAULT_CONFIG=newMatrixToImageConfig();privateMatrixToImageWriter(){}/***Rendersa{@linkBitMatrix}asanimage,where"false"bitsarerendered*aswhite,and"true"bitsarerenderedasblack.*/privatestaticBufferedImagetoBufferedImage(BitMatrixmatrix){returntoBufferedImage(matrix,DEFAULT_CONFIG);}/***As{@link#toBufferedImage(BitMatrix)},butallowscustomizationoftheoutput.*/privatestaticBufferedImagetoBufferedImage(BitMatrixmatrix,MatrixToImageConfigconfig){intwidth=matrix.getWidth();intheight=matrix.getHeight();BufferedImageimage=newBufferedImage(width,height,config.getBufferedImageColorModel());intonColor=config.getPixelOnColor();intoffColor=config.getPixelOffColor();for(intx=0;ximage.setRGB(x,y,matrix.get(x,y)?onColor:offColor);}}returnimage;}/***@deprecateduse{@link#writeToPath(BitMatrix,String,Path)}*/@DeprecatedprivatestaticvoidwriteToFile(BitMatrixmatrix,Stringformat,Filefile)throwsIOException{writeToPath(matrix,format,file.toPath());}/***Writesa{@linkBitMatrix}toafile.**@see#toBufferedImage(BitMatrix)*/privatestaticvoidwriteToPath(BitMatrixmatrix,Stringformat,Pathfile)throwsIOException{writeToPath(matrix,format,file,DEFAULT_CONFIG);}/***@deprecateduse{@link#writeToPath(BitMatrix,String,Path,MatrixToImageConfig)}*/@DeprecatedprivatestaticvoidwriteToFile(BitMatrixmatrix,Stringformat,Filefile,MatrixToImageConfigconfig)throwsIOException{writeToPath(matrix,format,file.toPath(),config);}/***As{@link#writeToFile(BitMatrix,String,File)},butallowscustomizationoftheoutput.*/@SuppressWarnings("all")privatestaticvoidwriteToPath(BitMatrixmatrix,Stringformat,Pathfile,MatrixToImageConfigconfig)throwsIOException{BufferedImageimage=toBufferedImage(matrix,config);if(!ImageIO.write(image,format,file.toFile())){thrownewIOException("Couldnotwriteanimageofformat"+format+"to"+file);}}/***Writesa{@linkBitMatrix}toastream.**@see#toBufferedImage(BitMatrix)*/privatestaticvoidwriteToStream(BitMatrixmatrix,Stringformat,OutputStreamstream)throwsIOException{writeToStream(matrix,format,stream,DEFAULT_CONFIG);}/***As{@link#writeToStream(BitMatrix,String,OutputStream)},butallowscustomization*oftheoutput.*/privatestaticvoidwriteToStream(BitMatrixmatrix,Stringformat,OutputStreamstream,MatrixToImageConfigconfig)throwsIOException{BufferedImageimage=toBufferedImage(matrix,config);if(!ImageIO.write(image,format,stream)){thrownewIOException("Couldnotwriteanimageofformat【"+format+"】");}}/***配置类封装*
*Encapsulatescustomconfigurationusedinmethodsof{@linkMatrixToImageWriter}.*/privatestaticclassMatrixToImageConfig{privatestaticfinalintBLACK=Color.BLACK.getRGB();privatestaticfinalintWHITE=Color.WHITE.getRGB();privatefinalintonColor;privatefinalintoffColor;/***Createsadefaultconfigwithoncolor{@link#BLACK}andoffcolor{@link#WHITE},*generatingnormal*black-on-whitebarcodes.*/privateMatrixToImageConfig(){this(BLACK,WHITE);}/***@paramonColor*pixeloncolor,specifiedasanARGBvalueasanint*@paramoffColor*pixeloffcolor,specifiedasanARGBvalueasanint*/privateMatrixToImageConfig(intonColor,intoffColor){this.onColor=onColor;this.offColor=offColor;}privateintgetPixelOnColor(){returnonColor;}privateintgetPixelOffColor(){returnoffColor;}privateintgetBufferedImageColorModel(){//UsefasterBINARYifcolorsmatchdefaultreturnonColor==BLACK&&offColor==WHITE?BufferedImage.TYPE_BYTE_BINARY:BufferedImage.TYPE_INT_RGB;}}}}
声明:此工具类由本人二次整理改造后分享给大家,原编写者未知,虽然本人重写了大部分逻辑代码,但是核心部分仍然是采用的原来的代码。若涉及侵权问题,请随时联系笔者。
^_^如有不当之处,欢迎指正
^_^参考链接 https://blog.csdn.net/jam_fanatic/article/details/82818857
^_^本文已经被收录进《程序员成长笔记》,笔者JustryDeng