Java?zxing實(shí)現(xiàn)生成并解析二維碼與條形碼
1、maven依賴
<!--zxing依賴--> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.1.0</version> </dependency>
2、一些重要屬性方法
BarcodeFormat (碼類型)
設(shè)置生成條形碼的類型。
如:二維碼、EAN-13碼、UPC-A碼、Code-128碼、Code-39碼等等。
條形碼類型 |
BarcodeFormat.AZTEC 阿茲特克碼 |
BarcodeFormat.CODABAR Codabar碼 |
BarcodeFormat.CODE_39 CODE-30碼 |
BarcodeFormat.CODE_93 CODE-93碼 |
BarcodeFormat.CODE_128 CODE-128碼 |
BarcodeFormat.DATA_MATRIX 矩陣式二維條碼 |
BarcodeFormat.EAN_8 EAN-8碼 |
BarcodeFormat.EAN_13 EAN-13碼 |
BarcodeFormat.ITF 交插二五條碼 |
BarcodeFormat.MAXICODE MaxiCode二維條碼 |
BarcodeFormat.PDF_417 ; PDF417 |
BarcodeFormat.QR_CODE 二維碼 |
BarcodeFormat.RSS_14 RSS 14 |
BarcodeFormat.RSS_EXPANDED RSS EXPANDED |
BarcodeFormat.UPC_A UPC A |
BarcodeFormat.UPC_E UPC E |
BarcodeFormat.UPC_EAN_EXTENSION UPC EAN EXTENSION |
EncodeHintType(自定義屬性)
3、帶logo得到二維碼生成
/** * @description: 二維碼生成 * @author: HK * @since: 2024/11/4 10:16 */ public class Test3 { private static final Integer CODE_WIDTH = 300; // 基礎(chǔ)屬性:二維碼寬度,單位像素 private static final Integer CODE_HEIGHT = 300; // 基礎(chǔ)屬性:二維碼高度,單位像素 private static final Integer FRONT_COLOR = 0x000000; // 基礎(chǔ)屬性:二維碼前景色,0x000000 表示黑色 private static final Integer BACKGROUND_COLOR = 0xFFFFFF; // 基礎(chǔ)屬性:二維碼背景色,0xFFFFFF 表示白色 public static void main(String[] args) throws Exception { //設(shè)置生成二維碼的內(nèi)容 String qrMessage = "https://www.baidu.com"; // EncodeHintType:編碼提示類型,枚舉類型 // EncodeHintType.CHARACTER_SET:設(shè)置字符編碼類型 // EncodeHintType.ERROR_CORRECTION:設(shè)置誤差校正 // ErrorCorrectionLevel:誤差校正等級, // L = ~7% correction、M = ~15% correction、 // Q = ~25% correction、H = ~30% correction // 不設(shè)置時,默認(rèn)為 L 等級,等級不一樣,生成的圖案不同,但掃描的結(jié)果是一樣的 // EncodeHintType.MARGIN:設(shè)置二維碼邊距,單位像素,值越小,二維碼距離四周越近 Map<EncodeHintType, Object> typeObjectHashMap = new HashMap<EncodeHintType, Object>(); typeObjectHashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8"); typeObjectHashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); typeObjectHashMap.put(EncodeHintType.MARGIN, 1); // MultiFormatWriter:多格式寫入,這是一個工廠類,里面重載了兩個 encode 方法,用于寫入條形碼或二維碼 // encode(String contents,BarcodeFormat format,int width, int height,Map<EncodeHintType,?> hints) // 參數(shù)1:contents:條形碼/二維碼內(nèi)容 // 參數(shù)2:format:編碼類型,如 條形碼,二維碼 等 // 參數(shù)3:width:碼的寬度 // 參數(shù)4:height:碼的高度 // 參數(shù)5:hints:碼內(nèi)容的編碼類型 // BarcodeFormat:枚舉該程序包已知的條形碼格式,即創(chuàng)建何種碼,如 1 維的條形碼,2 維的二維碼 等 // BitMatrix:位(比特)矩陣或叫2D矩陣,也就是需要的二維碼 MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); BitMatrix bitMatrix = multiFormatWriter .encode(qrMessage, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, typeObjectHashMap); // java.awt.image.BufferedImage:具有圖像數(shù)據(jù)的可訪問緩沖圖像,實(shí)現(xiàn)了 RenderedImage 接口 // BitMatrix 的 get(int x, int y) 獲取比特矩陣內(nèi)容,指定位置有值,則返回true,將其設(shè)置為前景色,否則設(shè)置為背景色 // BufferedImage 的 setRGB(int x, int y, int rgb) 方法設(shè)置圖像像素 // 參數(shù)1 x:像素位置的橫坐標(biāo),即列 // 參數(shù)2 y:像素位置的縱坐標(biāo),即行 // 參數(shù)3 rgb:像素的值,采用 16 進(jìn)制,如 0xFFFFFF 白色 BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR); for (int x = 0; x < CODE_WIDTH; x++) { for (int y = 0; y < CODE_HEIGHT; y++) { bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR); } } // 把logo圖片設(shè)置到二維碼中間位置(若不想在二維碼中間插入logo圖片則不執(zhí)行此條代碼) insertLogoImage(bufferedImage, new FileInputStream("d://hello.jpg")); // javax.imageio.ImageIO java擴(kuò)展的圖像IO // write(RenderedImage im,String formatName,File output) // im:待寫入的圖像 // formatName:圖像寫入的格式 // output:寫入的圖像文件,文件不存在時會自動創(chuàng)建 // 即將保存的二維碼圖片文件 ImageIO.write(bufferedImage, "png", new FileOutputStream("d://hello.png")); } /*** * 為二維碼插入中間的logo圖片 * @param bufferedImage 二維碼圖片信息 * @param logoInput logo圖片位置 * @throws IOException 拋出IO異常 */ private static void insertLogoImage(BufferedImage bufferedImage, InputStream logoInput) throws IOException { // 加載Logo圖片到Image對象 Image logoImage = ImageIO.read(logoInput); // 設(shè)置二維碼中間的Logo圖片(設(shè)置logo圖片的寬高需要保持和二維碼寬高的一半寬高) int logoWidth = CODE_WIDTH / 5; int logoHeight = CODE_HEIGHT / 5; // 按照指定的寬高進(jìn)行等比縮放(若設(shè)置的寬高比之前大則代表放大),并將縮放后的圖片繪制到一個新的BufferedImage對象中 Image image = logoImage.getScaledInstance(logoWidth, logoHeight, Image.SCALE_SMOOTH); BufferedImage logoBufferedImage = new BufferedImage(logoWidth, logoHeight, BufferedImage.TYPE_INT_RGB); // 獲取圖形上下文對象,用于后續(xù)將縮放后的圖片繪制在 logoBufferedImage 對象上 Graphics graphics = logoBufferedImage.getGraphics(); // 繪制縮放后的圖片到 logoBufferedImage 對象上,使其填滿整個畫布 graphics.drawImage(image, 0, 0, null); // 釋放圖形上下文對象,避免內(nèi)存泄漏 graphics.dispose(); // 把處理好的logo圖片再次設(shè)置給之前的logo圖片對象 logoImage = image; // 開始把logo圖片插入到二維碼的中間位置 // 獲取 Graphics2D 對象,用于后續(xù)在 bufferedImage 上繪制二維碼和 logo 圖片 Graphics2D graph = bufferedImage.createGraphics(); // 計(jì)算出 logo 圖片在二維碼中間的坐標(biāo)點(diǎn) (x, y),以便后續(xù)將 logo 圖片插入到正確的位置。 int x = (CODE_WIDTH - logoWidth) / 2; int y = (CODE_HEIGHT - logoHeight) / 2; // 繪制縮放后的 logo 圖片到二維碼中間位置 graph.drawImage(logoImage, x, y, logoWidth, logoHeight, null); // 設(shè)置邊框的線條粗細(xì)為 3 像素,并且設(shè)置線條是一個圓角矩形,6表示圓角的半徑。并關(guān)閉資源 graph.setStroke(new BasicStroke(3f)); graph.draw(new RoundRectangle2D.Float(x, y, logoWidth, logoHeight, 6, 6)); graph.dispose(); } }
4、解析二維碼
/** * 二維碼解析 * * @author Anhui OuYang * @version 1.0 **/ public class QRCodeParsing { public static void main(String[] args) throws Exception { System.out.println("=========================二維碼解析 Start========================="); parsingQRCode(new File("d://222.png")); System.out.println("=========================二維碼解析 End========================="); } /*** * 二維碼(QR_CODE)解析 * @param file 文件路徑信息 */ public static void parsingQRCode(File file) throws IOException, NotFoundException { //創(chuàng)建一個圖像數(shù)據(jù)緩沖區(qū)類(并讀取二維碼圖片) BufferedImage bufferedImage = ImageIO.read(file); // 對圖片信息的圖像處理和分析 // 注意需要 zxing 庫的版本 3.2.1 或更高版本才能使用,若沒有則使用我下面定義的getRGBPixelData(BufferedImage image) BufferedImageLuminanceSource luminanceSource = new BufferedImageLuminanceSource(bufferedImage); // 若版本不夠則使用這種方式 // RGBLuminanceSource luminanceSource = new RGBLuminanceSource(bufferedImage.getWidth(), // bufferedImage.getHeight(), getRGBPixelData(bufferedImage)); // 創(chuàng)建BinaryBitmap對象 // BinaryBitmap是二值化位圖,將像素從RGB空間轉(zhuǎn)換為黑白顏色空間 BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(luminanceSource)); // 設(shè)置解碼參數(shù) Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>(); hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); // 設(shè)置解析的字符集 // 使用 MultiFormatReader 進(jìn)行解碼 MultiFormatReader formatReader = new MultiFormatReader(); formatReader.setHints(hints); // 設(shè)置解碼一些參數(shù) Result result = formatReader.decode(binaryBitmap); // 解碼(解析binaryBitmap數(shù)據(jù)) // 打印一些信息 System.out.println("二維碼解析圖片的路徑: " + file.getPath()); System.out.println("二維碼解析圖片中格式: " + result.getBarcodeFormat()); System.out.println("二維碼解析圖片中內(nèi)容: " + result.getText()); } }
5、條形碼
簡單條形碼(無文字)
public class GenerateBarcode { private static final Integer CODE_WIDTH = 300; // 基礎(chǔ)屬性:二維碼寬度,單位像素 private static final Integer CODE_HEIGHT = 150; // 基礎(chǔ)屬性:二維碼高度,單位像素 private static final Integer FRONT_COLOR = 0x000000; // 基礎(chǔ)屬性:二維碼前景色,0x000000 表示黑色 private static final Integer BACKGROUND_COLOR = 0xFFFFFF; // 基礎(chǔ)屬性:二維碼背景色,0xFFFFFF 表示白色 public static void main(String[] args) throws Exception { //設(shè)置生成條形碼的內(nèi)容(注:條形碼信息一定要按照格式,如隨便一個商品上的條形碼都行,但必須是EAN_13格式) String qrMessage = "6971483746515"; // EncodeHintType:指定和控制碼生成器的一些參數(shù)的類 Map<EncodeHintType, Object> typeObjectHashMap = new HashMap<EncodeHintType, Object>(); // 設(shè)置編碼 typeObjectHashMap.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 設(shè)置容錯等級 typeObjectHashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 設(shè)置邊距,默認(rèn)為5 typeObjectHashMap.put(EncodeHintType.MARGIN, 3); // MultiFormatWriter:用于寫入條形碼或二維碼 MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); BitMatrix bitMatrix = multiFormatWriter .encode(qrMessage, BarcodeFormat.EAN_13, CODE_WIDTH, CODE_HEIGHT, typeObjectHashMap); // java.awt.image.BufferedImage:把條形碼信息轉(zhuǎn)換為圖像信息 BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR); for (int x = 0; x < CODE_WIDTH; x++) { for (int y = 0; y < CODE_HEIGHT; y++) { bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR); } } // javax.imageio.ImageIO 將圖片信息寫出到文件 ImageIO.write(bufferedImage, "png", new FileOutputStream("d://222.png")); } }
條形碼(含文字)
/** * 一個簡單的條形碼生成 * * @author Anhui OuYang * @version 1.0 **/ public class GenerateBarcode { private static final Integer CODE_WIDTH = 300; // 基礎(chǔ)屬性:二維碼寬度,單位像素 private static final Integer CODE_HEIGHT = 150; // 基礎(chǔ)屬性:二維碼高度,單位像素 private static final Integer FRONT_COLOR = 0x000000; // 基礎(chǔ)屬性:二維碼前景色,0x000000 表示黑色 private static final Integer BACKGROUND_COLOR = 0xFFFFFF; // 基礎(chǔ)屬性:二維碼背景色,0xFFFFFF 表示白色 public static void main(String[] args) throws Exception { // 條形碼底部內(nèi)容 String bottomStr = "123456"; // 條形碼左上角內(nèi)容 //String topLeftStr = name.length() < 11 ? name : name.substring(0, 11); String topLeftStr = "ceshi"; // 條形碼右上角內(nèi)容 String topRightStr = "2024-11-4"; // 生成條形碼 BufferedImage barCodeImage = create(bottomStr, 250, 50); BufferedImage withWords = createWithWords( barCodeImage, bottomStr, topLeftStr, topRightStr, 250, 150, 10, 14); ImageIO.write(withWords, "png", new FileOutputStream("d://222.png")); barCodeImage = create(bottomStr, 350, 70); withWords = createWithWords( barCodeImage, bottomStr, topLeftStr, topRightStr, 350, 210, 14, 20); ImageIO.write(withWords, "png", new FileOutputStream("d://333.png")); barCodeImage = create(bottomStr, 500, 100); withWords = createWithWords( barCodeImage, bottomStr, topLeftStr, topRightStr, 500, 300, 20, 28); ImageIO.write(withWords, "png", new FileOutputStream("d://444.png")); } /** * 生成簡單條形碼(無文字) * * @param content * @param width * @param height * @return */ public static BufferedImage create(String content, int width, int height) { // 定義位圖矩陣BitMatrix BitMatrix matrix = null; try { // 定義二維碼參數(shù) Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(3); // 設(shè)置編碼 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 設(shè)置容錯等級 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 設(shè)置邊距,默認(rèn)為5 hints.put(EncodeHintType.MARGIN, 3); // 使用code_128格式進(jìn)行編碼生成條形碼 MultiFormatWriter writer = new MultiFormatWriter(); matrix = writer.encode(content, BarcodeFormat.CODE_128, width, height, hints); } catch (WriterException e) { e.printStackTrace(); //throw new RuntimeException("條形碼內(nèi)容寫入失敗"); } return MatrixToImageWriter.toBufferedImage(matrix); } /** * 生成條形碼(含文字) * **************************************************** * ---------------------------------------------- * | 2023-06-10 10:55 | * | | * | 商品名稱 /超出不顯示/ | * | | * | | || ||| | || |||| | | | ||| | | || | * | | || ||| | || |||| | | | ||| | | || | * | | || ||| | || |||| | | | ||| | | || | * | | || ||| | || |||| | | | ||| | | || | * | 13800000000 | * ---------------------------------------------- * =================================================== * 1、日期:頂部右側(cè) * 2、商品名稱:居中 * 3、條形碼:商品名稱下方,且居中 * 4、條碼內(nèi)容:條形碼下方,且居中 * ***************************************************** * * @param codeImage 條形碼圖片 * @param bottomStr 底部文字 * @param titleStr 標(biāo)題文字 * @param topRightStr 右上角文字 * @param pictureWidth 圖片寬度 * @param pictureHeight 圖片高度 * @param margin 邊距 * @param fontSize 字體大小 * @return 條形碼圖片 */ private static BufferedImage createWithWords( BufferedImage codeImage, String bottomStr, String titleStr, String topRightStr, int pictureWidth, int pictureHeight, int margin, int fontSize) { BufferedImage picImage = new BufferedImage(pictureWidth, pictureHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = picImage.createGraphics(); // 抗鋸齒 setGraphics2D(g2d); // 設(shè)置白色 setColorWhite(g2d, picImage.getWidth(), picImage.getHeight()); // 條形碼默認(rèn)居中顯示 int codeStartX = (pictureWidth - codeImage.getWidth()) / 2; int codeStartY = (pictureHeight - codeImage.getHeight()) / 2 + 2 * margin; // 畫條形碼到新的面板 g2d.drawImage(codeImage, codeStartX, codeStartY, codeImage.getWidth(), codeImage.getHeight(), null); // 給條碼上下各畫一條線 // 設(shè)置顏色 g2d.setColor(Color.LIGHT_GRAY); int y1 = 2 * margin + codeImage.getHeight(); int y2 = 2 * margin + 2 * codeImage.getHeight(); g2d.drawLine(0, y1, pictureWidth, y1); g2d.drawLine(0, y2, pictureWidth, y2); // 畫文字到新的面板 g2d.setColor(Color.BLACK); // 字體、字型、字號 g2d.setFont(new Font("微軟雅黑", Font.PLAIN, fontSize)); // 文字與條形碼之間的間隔 int wordAndCodeSpacing = 3; // 底部文字(居中) if (StringUtils.isNotEmpty(bottomStr)) { // 文字長度 int strWidth = g2d.getFontMetrics().stringWidth(bottomStr); // 文字X軸開始坐標(biāo) int strStartX = (pictureWidth - strWidth) / 2; if (strStartX < margin) { strStartX = margin; } // 文字Y軸開始坐標(biāo) int strStartY = codeStartY + codeImage.getHeight() + fontSize + wordAndCodeSpacing; // 畫文字 g2d.drawString(bottomStr, strStartX, strStartY); } // 右上角文字 if (StringUtils.isNotEmpty(topRightStr)) { // 文字長度 int strWidth = g2d.getFontMetrics().stringWidth(topRightStr); // 文字X軸開始坐標(biāo) int strStartX = pictureWidth - strWidth - margin; // 文字Y軸開始坐標(biāo) int strStartY = margin + fontSize; // 畫文字 g2d.drawString(topRightStr, strStartX, strStartY); } // 標(biāo)題文字(居中) if (StringUtils.isNotEmpty(titleStr)) { if (titleStr.length() > 11) { titleStr = titleStr.substring(0, 11); } // 字體、字型、字號 int fs = (int) Math.ceil(fontSize * 1.5); g2d.setFont(new Font("微軟雅黑", Font.PLAIN, fs)); // 文字長度 int strWidth = g2d.getFontMetrics().stringWidth(titleStr); // 文字X軸開始坐標(biāo) int strStartX = (pictureWidth - strWidth) / 2; if (strStartX < margin) { strStartX = margin; } // 文字Y軸開始坐標(biāo) int strStartY = codeStartY - margin; // 畫文字 g2d.drawString(titleStr, strStartX, strStartY); } g2d.dispose(); picImage.flush(); return picImage; } /** * 設(shè)置 Graphics2D 屬性 (抗鋸齒) * * @param g2d Graphics2D提供對幾何形狀、坐標(biāo)轉(zhuǎn)換、顏色管理和文本布局更為復(fù)雜的控制 */ private static void setGraphics2D(Graphics2D g2d) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_DEFAULT); Stroke s = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER); g2d.setStroke(s); } /** * 設(shè)置背景為白色 * * @param g2d Graphics2D提供對幾何形狀、坐標(biāo)轉(zhuǎn)換、顏色管理和文本布局更為復(fù)雜的控制 */ private static void setColorWhite(Graphics2D g2d, int width, int height) { g2d.setColor(Color.WHITE); // 填充整個屏幕 g2d.fillRect(0, 0, width, height); // 設(shè)置筆刷 g2d.setColor(Color.BLACK); } }
解析條形碼
以上就是Java zxing實(shí)現(xiàn)生成并解析二維碼與條形碼的詳細(xì)內(nèi)容,更多關(guān)于Java zxing解析二維碼與條形碼的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot實(shí)現(xiàn)國際化的操作步驟
國際化(Internationalization) 是指為了適應(yīng)不同語言、文化和地區(qū)的用戶,使軟件能夠方便地進(jìn)行本地化修改的過程,本文介紹了SpringBoot 國際化功能的簡單使用,感興趣的朋友可以參考下2024-02-02arthas在idea和docker中的應(yīng)用方式
這篇文章主要介紹了arthas在idea和docker中的應(yīng)用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-10-10Java實(shí)現(xiàn)List轉(zhuǎn)換為Map的方法小結(jié)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)List轉(zhuǎn)換為Map的一些常見的方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以參考一下2024-03-03springboot整合token的實(shí)現(xiàn)代碼
這篇文章主要介紹了springboot整合token的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11java中數(shù)組list map三者之間的互轉(zhuǎn)介紹
java中 數(shù)組 list map之間的互轉(zhuǎn)一張圖清晰呈現(xiàn)并附有代碼,不懂的朋友可以參考下2013-10-10