| | |
| | | package com.ruoyi.service.impl; |
| | | |
| | | import com.google.zxing.BarcodeFormat; |
| | | import com.google.zxing.EncodeHintType; |
| | | import com.google.zxing.WriterException; |
| | | import com.google.zxing.common.BitMatrix; |
| | | import com.google.zxing.oned.Code128Writer; |
| | | import com.google.zxing.oned.Code39Writer; |
| | | import org.krysalis.barcode4j.impl.code128.Code128Bean; |
| | | import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.imageio.ImageIO; |
| | | import java.awt.*; |
| | | import java.awt.image.BufferedImage; |
| | | import java.io.ByteArrayInputStream; |
| | | import java.io.ByteArrayOutputStream; |
| | | import java.io.IOException; |
| | | import java.lang.reflect.Method; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | @Service |
| | | |
| | | public class BarcodeService { |
| | | public byte[] generateBarcodeImage(String barcodeText) { |
| | | try { |
| | | Code128Bean barcodeGenerator = new Code128Bean(); |
| | | final int dpi = 160; |
| | | barcodeGenerator.setModuleWidth(0.58); |
| | | barcodeGenerator.setBarHeight(14.2); // 设置条形码高度为64 |
| | | barcodeGenerator.doQuietZone(false); |
| | | // 使用 BitMatrix 生成纯条码,不包含任何文字 |
| | | BarcodeFormat format = BarcodeFormat.CODE_128; // 根据您的条码类型 |
| | | |
| | | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); |
| | | BitmapCanvasProvider canvas = new BitmapCanvasProvider( |
| | | outputStream, "image/png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0); |
| | | // 创建编码器 |
| | | Code128Writer writer = new Code128Writer(); |
| | | |
| | | barcodeGenerator.generateBarcode(canvas, barcodeText); |
| | | canvas.finish(); |
| | | // 编码参数 |
| | | Map<EncodeHintType, Object> hints = new HashMap<>(); |
| | | hints.put(EncodeHintType.MARGIN, 0); // 无边框 |
| | | |
| | | return outputStream.toByteArray(); |
| | | // 生成 BitMatrix(纯条码,无文字) |
| | | BitMatrix matrix = writer.encode(barcodeText, format, 0, 63, hints); |
| | | |
| | | int width = matrix.getWidth(); |
| | | int height = matrix.getHeight(); |
| | | |
| | | // 计算文字区域 |
| | | int textAreaHeight = 30 + 10; |
| | | |
| | | // 创建最终图像 |
| | | BufferedImage finalImage = new BufferedImage( |
| | | width, |
| | | height + textAreaHeight, |
| | | BufferedImage.TYPE_BYTE_BINARY |
| | | ); |
| | | |
| | | Graphics2D g2d = finalImage.createGraphics(); |
| | | |
| | | // 白色背景 |
| | | g2d.setColor(Color.WHITE); |
| | | g2d.fillRect(0, 0, width, height + textAreaHeight); |
| | | |
| | | // 绘制条码(从 BitMatrix) |
| | | g2d.setColor(Color.BLACK); |
| | | for (int x = 0; x < width; x++) { |
| | | for (int y = 0; y < height; y++) { |
| | | if (matrix.get(x, y)) { |
| | | g2d.fillRect(x, y, 1, 1); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 添加自定义文字 |
| | | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); |
| | | g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); |
| | | g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); |
| | | g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); |
| | | |
| | | Font font = new Font("Tahoma", Font.PLAIN, 20); |
| | | g2d.setFont(font); |
| | | |
| | | FontMetrics fm = g2d.getFontMetrics(); |
| | | int textWidth = fm.stringWidth(barcodeText); |
| | | int x = (width - textWidth) / 2; |
| | | int y = height + 30 - 5; // 调整垂直位置 |
| | | |
| | | g2d.drawString(barcodeText, x, y); |
| | | g2d.dispose(); |
| | | |
| | | // 保存 |
| | | ByteArrayOutputStream resultStream = new ByteArrayOutputStream(); |
| | | ImageIO.write(finalImage, "png", resultStream); |
| | | |
| | | return resultStream.toByteArray(); |
| | | // return outputStream.toByteArray(); |
| | | } catch (IOException e) { |
| | | throw new RuntimeException("Error generating barcode", e); |
| | | } catch (WriterException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | } |