1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
| /** * CODE_WIDTH:二维码宽度,单位像素 * CODE_HEIGHT:二维码高度,单位像素 * FRONT_COLOR:二维码前景色,0x000000 表示黑色 * BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色 * IMAGE_WIDTH:二维码中间图标内框宽度 * IMAGE_HEIGHT: 二维码中间图标内框高度 * 演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白 */ private static final int CODE_WIDTH = 512; private static final int CODE_HEIGHT = 512; private static final int IMAGE_WIDTH = 100; private static final int IMAGE_HEIGHT = 100; private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2; private static final int FRAME_WIDTH = 2; private static MultiFormatWriter mutiWriter = new MultiFormatWriter();
/** * 生成彩色二维码 并 保存为图片 * * @param content * @param srcImagePath */ public static void createColorCodeToFile(String content, String srcImagePath) { try { //获取系统目录 String filePathDir = FileSystemView.getFileSystemView().getHomeDirectory().getAbsolutePath(); //随机生成 png 格式图片 String fileName = new Date().getTime() + ".png"; BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH, IMAGE_HEIGHT, true); int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT]; for (int i = 0; i < scaleImage.getWidth(); i++) { for (int j = 0; j < scaleImage.getHeight(); j++) { srcPixels[i][j] = scaleImage.getRGB(i, j); } } Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); hints.put(EncodeHintType.MARGIN, 1); // 生成二维码 BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints); // 二维矩阵转为一维像素数组 int halfW = matrix.getWidth() / 2; int halfH = matrix.getHeight() / 2; int[] pixels = new int[CODE_WIDTH * CODE_HEIGHT]; for (int y = 0; y < matrix.getHeight(); y++) { for (int x = 0; x < matrix.getWidth(); x++) { // 左上角颜色,根据自己需要调整颜色范围和颜色 if (x > 0 && x < 170 && y > 0 && y < 170) { Color color = new Color(231, 144, 56); int colorInt = color.getRGB(); pixels[y * CODE_WIDTH + x] = matrix.get(x, y) ? colorInt : 16777215; } // 读取图片 else if (x > halfW - IMAGE_HALF_WIDTH && x < halfW + IMAGE_HALF_WIDTH && y > halfH - IMAGE_HALF_WIDTH && y < halfH + IMAGE_HALF_WIDTH) { pixels[y * CODE_WIDTH + x] = srcPixels[x - halfW + IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH]; } else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH - IMAGE_HALF_WIDTH + FRAME_WIDTH) || (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH && x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH && y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH + IMAGE_HALF_WIDTH + FRAME_WIDTH)) { pixels[y * CODE_WIDTH + x] = 0xfffffff; // 在图片四周形成边框 } else { // 二维码颜色 int num1 = (int) (50 - (50.0 - 13.0) / matrix.getHeight() * (y + 1)); int num2 = (int) (165 - (165.0 - 72.0) / matrix.getHeight() * (y + 1)); int num3 = (int) (162 - (162.0 - 107.0) / matrix.getHeight() * (y + 1)); Color color = new Color(num1, num2, num3); int colorInt = color.getRGB(); // 此处可以修改二维码的颜色,可以分别制定二维码和背景的颜色; pixels[y * CODE_WIDTH + x] = matrix.get(x, y) ? colorInt : 16777215; // 0x000000:0xffffff } } } BufferedImage image = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_RGB); image.getRaster().setDataElements(0, 0, CODE_WIDTH, CODE_HEIGHT, pixels); File codeImgFile = new File(filePathDir, fileName); ImageIO.write(image, "jpg", codeImgFile); System.out.println("二维码图片生成成功:" + codeImgFile.getPath()); } catch (IOException e) { e.printStackTrace(); } catch (WriterException e) { e.printStackTrace(); } }
private static BufferedImage scale(String srcImageFile, int height, int width, boolean hasFiller) throws IOException { double ratio = 0.0; // 缩放比例 File file = new File(srcImageFile); BufferedImage srcImage = ImageIO.read(file); Image destImage = srcImage.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH); // 计算比例 if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) { if (srcImage.getHeight() > srcImage.getWidth()) { ratio = (new Integer(height)).doubleValue() / srcImage.getHeight(); } else { ratio = (new Integer(width)).doubleValue() / srcImage.getWidth(); } AffineTransformOp op = new AffineTransformOp( AffineTransform.getScaleInstance(ratio, ratio), null); destImage = op.filter(srcImage, null); } if (hasFiller) { // 补白 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D graphic = image.createGraphics(); graphic.setColor(Color.white); 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; }
|