| | |
| | | @Service |
| | | |
| | | public class BarcodeService { |
| | | public byte[] generateBarcodeImage(String barcodeText) { |
| | | /** |
| | | * 添加文字到条码(优化版本) |
| | | */ |
| | | private void addTextToBarcode(Graphics2D g2d, String text, int width, int barcodeHeight) { |
| | | 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); |
| | | |
| | | // 使用更清晰的字体 |
| | | Font font = new Font("Tahoma", Font.PLAIN, 45); |
| | | g2d.setFont(font); |
| | | g2d.setColor(Color.BLACK); |
| | | |
| | | // 计算文字位置 |
| | | FontMetrics fm = g2d.getFontMetrics(); |
| | | int textWidth = fm.stringWidth(text); |
| | | int textHeight = fm.getHeight(); |
| | | |
| | | // 居中对齐 |
| | | int x = (width - textWidth) / 2; |
| | | int y = barcodeHeight + textHeight - fm.getDescent(); // 精确垂直居中 |
| | | |
| | | // 绘制文字 |
| | | g2d.drawString(text, x, y); |
| | | } |
| | | public byte[] generateBarcodeImage(String barcodeText) { |
| | | try { |
| | | BarcodeFormat format = BarcodeFormat.CODE_39; |
| | | Code39Writer writer = new Code39Writer(); |
| | | |
| | | // 编码参数 - 设置边距为0 |
| | | Map<EncodeHintType, Object> hints = new HashMap<>(); |
| | | hints.put(EncodeHintType.MARGIN, 0); // 关键:设置边距为0 |
| | | |
| | | // 生成 BitMatrix(纯条码,无文字) |
| | | // 注意:即使设置了MARGIN=0,ZXing可能仍会保留最小边距 |
| | | BitMatrix matrix = writer.encode(barcodeText, format, 1300, 141, hints); |
| | | |
| | | // 方案1.1:直接裁剪白边 |
| | | return generateBarcodeWithCroppedMargin(matrix, barcodeText); |
| | | } |
| | | catch (IOException e) { |
| | | throw new RuntimeException("Error generating barcode", e); |
| | | } catch (WriterException e) { |
| | | throw new RuntimeException(e); |
| | | } |
| | | } |
| | | |
| | | private byte[] generateBarcodeWithCroppedMargin(BitMatrix matrix, String barcodeText) throws IOException { |
| | | int width = matrix.getWidth(); |
| | | int height = matrix.getHeight(); |
| | | |
| | | // 找到条码的实际边界 |
| | | int left = findLeftBoundary(matrix); |
| | | int right = findRightBoundary(matrix); |
| | | int top = findTopBoundary(matrix); |
| | | int bottom = findBottomBoundary(matrix); |
| | | |
| | | // 计算条码的实际宽度和高度 |
| | | int barcodeWidth = right - left + 1; |
| | | int barcodeHeight = bottom - top + 1; |
| | | |
| | | // 计算文字区域高度 |
| | | int textAreaHeight = 30 + 27; |
| | | |
| | | // 创建最终图像(精确尺寸) |
| | | BufferedImage finalImage = new BufferedImage( |
| | | barcodeWidth, |
| | | barcodeHeight + textAreaHeight, |
| | | BufferedImage.TYPE_BYTE_BINARY |
| | | ); |
| | | |
| | | Graphics2D g2d = finalImage.createGraphics(); |
| | | |
| | | // 白色背景 |
| | | g2d.setColor(Color.WHITE); |
| | | g2d.fillRect(0, 0, barcodeWidth, barcodeHeight + textAreaHeight); |
| | | |
| | | // 绘制条码(只绘制有效部分) |
| | | g2d.setColor(Color.BLACK); |
| | | for (int x = left; x <= right; x++) { |
| | | for (int y = top; y <= bottom; y++) { |
| | | if (matrix.get(x, y)) { |
| | | g2d.fillRect(x - left, y - top, 1, 1); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 添加自定义文字 |
| | | addTextToBarcode(g2d, barcodeText, barcodeWidth, barcodeHeight); |
| | | |
| | | g2d.dispose(); |
| | | |
| | | // 保存 |
| | | ByteArrayOutputStream resultStream = new ByteArrayOutputStream(); |
| | | ImageIO.write(finalImage, "png", resultStream); |
| | | |
| | | return resultStream.toByteArray(); |
| | | } |
| | | |
| | | // 辅助方法:找到条码的边界 |
| | | private int findLeftBoundary(BitMatrix matrix) { |
| | | int width = matrix.getWidth(); |
| | | int height = matrix.getHeight(); |
| | | |
| | | for (int x = 0; x < width; x++) { |
| | | for (int y = 0; y < height; y++) { |
| | | if (matrix.get(x, y)) { |
| | | return x; |
| | | } |
| | | } |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | private int findRightBoundary(BitMatrix matrix) { |
| | | int width = matrix.getWidth(); |
| | | int height = matrix.getHeight(); |
| | | |
| | | for (int x = width - 1; x >= 0; x--) { |
| | | for (int y = 0; y < height; y++) { |
| | | if (matrix.get(x, y)) { |
| | | return x; |
| | | } |
| | | } |
| | | } |
| | | return width - 1; |
| | | } |
| | | |
| | | private int findTopBoundary(BitMatrix matrix) { |
| | | int width = matrix.getWidth(); |
| | | int height = matrix.getHeight(); |
| | | |
| | | for (int y = 0; y < height; y++) { |
| | | for (int x = 0; x < width; x++) { |
| | | if (matrix.get(x, y)) { |
| | | return y; |
| | | } |
| | | } |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | private int findBottomBoundary(BitMatrix matrix) { |
| | | int width = matrix.getWidth(); |
| | | int height = matrix.getHeight(); |
| | | |
| | | for (int y = height - 1; y >= 0; y--) { |
| | | for (int x = 0; x < width; x++) { |
| | | if (matrix.get(x, y)) { |
| | | return y; |
| | | } |
| | | } |
| | | } |
| | | return height - 1; |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | public byte[] generateBarcodeImage1(String barcodeText) { |
| | | try { |
| | | // 使用 BitMatrix 生成纯条码,不包含任何文字 |
| | | BarcodeFormat format = BarcodeFormat.CODE_39; // 根据您的条码类型 |
| | |
| | | hints.put(EncodeHintType.MARGIN, 0); // 无边框 |
| | | |
| | | // 生成 BitMatrix(纯条码,无文字) |
| | | BitMatrix matrix = writer.encode(barcodeText, format, 230, 63, hints); |
| | | BitMatrix matrix = writer.encode(barcodeText, format, 1128, 199, hints); |
| | | |
| | | int width = matrix.getWidth(); |
| | | int height = matrix.getHeight(); |