私たちは、jarファイルを導入する必要があります。
<! - https://mvnrepository.com/artifact/com.google.zxing/core - > <依存> <groupIdを> com.google.zxing </ groupIdを> <たartifactId>コア</たartifactId> <バージョン> 3.4.0 </バージョン> </依存関係>
そして、ツールQRCodeUtilとBufferedImageLuminanceSource:
輸入java.awt.BasicStroke; 輸入java.awt.Graphics; 輸入java.awt.Graphics2D; 輸入はjava.awt.Image; 輸入java.awt.Shape。 輸入java.awt.geom.RoundRectangle2D; 輸入java.awt.image.BufferedImage。 インポートのjava.io.File; インポートにjava.io.OutputStream; インポートするjava.util.Hashtable; 輸入java.util.Randomの。 輸入javax.imageio.ImageIO; 輸入com.google.zxing.BarcodeFormat。 輸入com.google.zxing.BinaryBitmap。 輸入com.google.zxing.DecodeHintType。 輸入com.google.zxing.EncodeHintType。 輸入com.google.zxing.MultiFormatReader。 輸入com.google.zxing.MultiFormatWriter。 輸入com.google.zxing.Result。 com.google.zxing.common.BitMatrixインポート; インポートcom.google.zxing.common.HybridBinarizer; インポートcom.google.zxing.qrcode.decoder.ErrorCorrectionLevel; publicクラスQRCodeUtil { プライベート静的文字列の最終CHARSET = "UTF-8"。 ; 民間最終静的文字列FORMAT_NAME = "JPG"; //二次元コードのサイズ プライベート静的INT QRCODE_SIZEファイナル= 300; // LOGO幅 民間最終静的INT幅= 60; //高さLOGO 民間最終静的INT高さ= 60; / ** * 2次元コードを生成する * @paramコンテンツソースのコンテンツ * @param imgPath保存された2次元コードパスを生成 しますが、圧縮するかどうか* @param needCompress 2次元コードの画像を返す@return * * @throws例外 バッファ画像イメージ=新しいBufferedImageの(幅、高さ、BufferedImage.TYPE_INT_RGB)。 * / プライベート静的たBufferedImageはcreateImage(文字列のコンテンツ、文字列imgPath、ブールneedCompress)は例外{スロー Hashtableのヒント=新しいハッシュテーブルを()。 hints.put(EncodeHintType.ERROR_CORRECTION、ErrorCorrectionLevel.H)。 hints.put(EncodeHintType.CHARACTER_SET、CHARSET)。 hints.put(EncodeHintType.MARGIN、1)。 BitMatrix bitMatrix =新しいMultiFormatWriter()(コンテンツ、BarcodeFormat.QR_CODE、QRCODE_SIZE、QRCODE_SIZE、エンコード。 ヒント)。 INT幅= bitMatrix.getWidth()。 INT高さ= bitMatrix.getHeight()。 {(; X <幅X ++整数X = 0)のための ための(INT Y = 0; yと<高さ; Y ++){ image.setRGB(X、Y、bitMatrix.get(X、Y)0xFF000000 :? 0xFFFFFFFFの); } } IF(imgpath == NULL || "" .equals (imgpath)){ 戻り画像; } //挿入画像 QRCodeUtil.insertImage(画像、imgpath、needCompress); 戻り画像; } / ** *生成された2次元コード画像に挿入 * @paramソース * @paramのimgpath * needCompress @param *例外を@throws * / プライベート静的ボイドinsertimage(BufferedImageのソース、文字列imgpath、ブールneedCompressは){例外がスローされます ファイルファイル=新しいファイル(imgPath)。 (もし!file.exists()){ グラフィックG = tag.getGraphics()。 System.err.println( "" + imgpath + "ファイル"が存在しません!); 返します。 } イメージ・SRC = ImageIO.read(新しいファイル(imgPath)); INT幅= src.getWidth(NULL)。 INT高さ= src.getHeight(NULL)。 IF(needCompress){//压缩LOGO 場合(幅> WIDTH){ 幅= WIDTH。 } IF(高さ>高さ){ 高さ= HEIGHT。 } イメージ画像= src.getScaledInstance(幅、高さ、Image.SCALE_SMOOTH)。 BufferedImageのタグ=新しいBufferedImageの(幅、高さ、BufferedImage.TYPE_INT_RGB)。 g.drawImage(イメージ、0、0、NULL); //绘制缩小后的图 g.dispose(); SRC =画像; } //挿入LOGO のGraphics2D source.createGraphicsグラフ=(); int型X =(QRCODE_SIZE -幅)/ 2。 Y = INT(QRCODE_SIZE -高さ)/ 2; graph.drawImage(SRC、X、Y、幅、高さ、NULL) ;新しい新=(X、Y、幅、幅,. 6 ,. 6)RoundRectangle2D.Float形形状 グラフ.setStroke((3F)を使用して新しい新規のBasicStroke); graph.draw(形状); graph.dispose(); } / ** *ロゴ付き二次元コードを生成し、ディスクに保存 * @paramコンテンツ * @paramのimgpathロゴイメージ * DESTPATH @param * @param needCompress * @throws例外 * / / ** imgFile =新しいファイル(DESTPATH + "/" +ファイル名)ファイル。 ロゴ入りの2次元コードを生成*、およびディスクに保存 * * @paramコンテンツ * @param imgPathロゴ图片 * @param DESTPATH * @param needCompress是否压缩 *例外@throws * @author lifq * * 2016年12月13日上午9時54分49秒 * / パブリック静的ファイルエンコード(文字列コンテンツ、文字imgPath、列DESTPATH、ブールneedCompress)は例外{スロー バッファ画像イメージを= QRCodeUtil.createImage(コンテンツ、imgPath、needCompress)。 mkdirs(DESTPATH)。 文字列filename =新しいランダム()nextInt(99999999)+ ".JPG"; //生成随机文件名 ImageIO.write(画像、FORMAT_NAME、imgFile)。 imgFileを返します。 } パブリック静的ボイドmkdirs(文字列DESTPATH){ ファイルファイル=新しい新しいファイル(DESTPATH); //フォルダが存在しない場合は、mkdirsが自動的にMKDIRは異なるいくつかのディレクトリを作成します。(MKDIRの親ディレクトリは、例外がスローされた場合は存在しない) 場合には(File.Exists()&& file.isDirectory()!){ file.mkdirs(); } } / ** *二次元コードを生成し、ディスクに保存内容 * * @author lifq * * 2016インディアン12 13午前9時56分42秒 * / パブリック静的ファイルのエンコード(文字列コンテンツ、imgpath文字列、文字列DESTPATH)が例外をスロー{ 、QRCodeUtil.encode(コンテンツ、imgpath、DESTPATHを返します)falseに; } / ** *二次元コードを生成し、ディスクのディレクトリに保存 * * @author lifq * 公共の静的な無効エンコード(内容文字列、文字列のimgpath、OutputStreamの出力、ブールneedCompress) * 9時56分42秒2016インディアン12 13朝 * / パブリック静的ファイルエンコード(文字列コンテンツは、文字列DESTPATH、ブールneedCompress)が例外をスロー{ QRCodeUtil.encode(コンテンツ、ヌル、DESTPATH、needCompress)を返します。 } / ** *生成二维码并保存到磁盘目录 * * @author lifq * * 9時56分42秒上午年12月13日2016 * / パブリック静的ファイルエンコードは、(文字列のコンテンツは、文字列DESTPATH)が例外をスロー{ リターンQRCodeUtil.encode(コンテンツ、ヌル、DESTPATH、偽); } スロー例外{ バッファ画像イメージ= QRCodeUtil.createImage(コンテンツ、imgPath、needCompress)。 ImageIO.write(画像、FORMAT_NAME、出力)。 } 静的ボイドエンコードパブリック(文字列コンテンツのOutputStream出力)例外スロー{ QRCodeUtil.encode(偽のコンテンツ、ヌル、出力を); } / ** *二次元コード、解析されたデータから *の@paramファイル次元コード画像ファイル * @return二次元コードのデータ値から解析戻る *例外@throws * / パブリック静的文字列デコード(ファイルファイル)が例外{スロー BufferedImageのイメージ、 イメージ= ImageIO.read(ファイル); IF(画像== NULL){ BinaryBitmapビットマップは=新しい新しいBinaryBitmap(新新HybridBinarizer(出所)); 結果結果; 戻りヌル。 } BufferedImageLuminanceSourceソース=新しいBufferedImageLuminanceSource(イメージ)。 ファイルファイル= QRCodeUtil.encode(テキスト、 "E:/data/1.jpg"、真の); Hashtableのヒント=新しいHashtableの(); hints.put(DecodeHintType.CHARACTER_SET、CHARSET)。 結果=新しいMultiFormatReader()(ビットマップ、ヒント)をデコードします。 ストリングresultStr = result.getText()。 resultStrを返します。 } パブリック静的文字列デコード(文字列のパス){例外をスロー QRCodeUtil.decode(新しいファイル(パス))を返します。 } 公共の静的な無効メイン(文字列[]引数)例外{スロー 文字列のテキスト=「http://www.baidu.com」と、 System.out.println( "生成二维码名称:" + file.getName()); 文字列のRES = QRCodeUtil.decode(ファイル); System.out.println( "解析的二维码内容:" + RES)。 } }
com.google.zxing.LuminanceSourceインポート、 インポートjava.awt.Graphics2D; インポートjava.awt.geom.AffineTransformのセット; インポートjava.awt.image.BufferedImage; / ** *など階層の目的は、異なるビットマップLuminanceSourceです輝度階調値を要求するためのクロスプラットフォーム規格インターフェース。このインタフェースは、抽象メソッドを提供し ますので、生成してコピーを作成するために回転させることができます*。これは、読者が元のソースの輝度を変更し、そして鎖中に未知の状態、他の読者にそれを持っていないことを保証することです。 Https://zxing.github.io/zxing/apidocs/com/google/zxing/LuminanceSource.html * * @author ljheee * * / publicクラスBufferedImageLuminanceSource LuminanceSource {拡張 プライベートイメージ決勝BufferedImageを、 民間最終int型左; 民間最終int型トップ; 公共BufferedImageLuminanceSource(BufferedImageのイメージ){ この(イメージ、0、0、image.getWidth()、image.getHeight())。 } / ** *构造方法 * @param画像 *左@param * @paramトップ * @param幅 * @param高 * / パブリックBufferedImageLuminanceSource {(バッファ画像イメージ、int型の高さ、INT幅、int型の上部を左INT) スーパー(幅、高さ); INT sourceWidth = image.getWidth()。 INT sourceHeight = image.getHeight()。 もし(左+幅> sourceWidth ||トップ+高さ> sourceHeight){ 新しいIllegalArgumentExceptionをスローし(「クロップ矩形は、画像データに収まりません。」); } (INT Y =頂; Y <トップ+高さ; Y ++)用{ ため(INT X =左; X <左+幅; X ++){ IF((image.getRGB(X、Y)&0xFF000000)== 0){ image.setRGB(X、Y、0xFFFFFFFFの); // =白 } } } this.image =新しいBufferedImageの(sourceWidth、sourceHeight、BufferedImage.TYPE_BYTE_GRAY)。 this.image.getGraphics()のdrawImage(イメージ、0、0、NULL)。 左= this.left。 this.top =トップ。 } @Override 公共バイト[]のgetRow(INT yを、バイト[]行){//从底层平台的位图提取一行(一つだけの行)的亮度数据值 (Y <0 || Y> =のgetHeight()もし){ 新をスロー(「要求された行は、画像の外にある」+ Y)。 } int型の幅=のgetWidth()。 IF(行== NULL || row.length <幅){ 列=新しいバイト[幅]。 } image.getRaster()getDataElements(左、トップ+ Y、幅、1行)。 行を返します。 } @Override 公共バイト[] getMatrix(){///从底层平台的位图提取亮度数据值 INT幅=のgetWidth()。 INT高さ=のgetHeight(); int型の面積=幅*高さ。 バイト[]マトリックス=新しいバイト[領域]。 image.getRaster()getDataElements(左、上、幅、高さ、マトリックス)。 行列を返します。 } @Override パブリックブールisCropSupported(){//是否支持裁剪 trueを返すように; } / ** *新しいオブジェクトとカットの画像データを返します。実装は、元のデータを参照するのではなく、コピーを保存することができます。 * / @Overrideは int型sourceHeight image.getHeight =(); たAffineTransformたAffineTransform新しい新しい変換=(0.0、-1.0、1.0、0.0、0.0、SourceWidth)。 公共LuminanceSourceクロップできます(左INT、INTトップ、int型の幅、int型の高さ){ 新しい新しいBufferedImageLuminanceSourceリターン(画像は、左this.left +、+トップthis.top、幅、高さ); } @Override 公共ブールisRotateSupported(){//サポート回転 trueに復帰; } @Override 公共LuminanceSource rotateCounterClockwise(){/ /画像データを90度反時計回りに回転され、新しいオブジェクトが返されます。 SourceWidth image.getWidth = INT(); INT幅=のgetWidth()。 BufferedImageのrotatedImage =新しいBufferedImageの(sourceHeight、sourceWidth、BufferedImage.TYPE_BYTE_GRAY)。 Graphics2D G = rotatedImage.createGraphics()。 g.drawImage(画像、変換、NULL); g.dispose(); 新しいBufferedImageLuminanceSourceを返す(rotatedImage、トップ、sourceWidth - (左+幅)、のgetHeight()、幅); } }
テープテスト。