Remind future self: when using the optimistic path changed a bit on the line <! - generated two-dimensional code -> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>${zxing.version}</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>android-core</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>android-integration</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>${zxing.version}</version> </dependency>
package com.sun.test.QRcode.AddLOGO; public class QrCodeTest { public static void main(String[] args) throws Exception { long start = System.currentTimeMillis(); // store the contents in the two-dimensional codes String text = "I'm Xiaoming Why Why Why Why Why"; // two-dimensional code embedded image path String imgPath = "http://shenghuoplus.oss-cn-shenzhen.aliyuncs.com/ Dish Images /779b931afa3f7910bc40b79b2cfb36aa.jpg"; // path and name of the generated two-dimensional code String destPath = "F:/play.png"; // generate two-dimensional code QRCodeUtil.encode(text, imgPath, destPath, true); long generateEnd = System.currentTimeMillis(); System.out.println ( "Time to generate two-dimensional code:" + (generateEnd - start)); // parse the two-dimensional code String str = QRCodeUtil.decode(destPath); System.out.println ( "resolved two-dimensional code:" + (System.currentTimeMillis () - generateEnd)); // print out the contents parsed System.out.println ( "print out the contents of the parsed:" + str); } }
package com.sun.test.QRcode.AddLOGO; import com.google.zxing.*; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io. *; import java.net.HttpURLConnection; import java.net.URL; import java.util.Hashtable; public class QRCodeUtil { private static final String CHARSET = "utf-8"; private static final String FORMAT_NAME = "JPG"; // size two-dimensional code private static final int QRCODE_SIZE = 300; // LOGO width private static final int WIDTH = 60; // LOGO height private static final int HEIGHT = 60; private static BufferedImage createImage(String content, String imgPath, boolean needCompress) throws Exception { Hashtable hints = new Hashtable(); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); hints.put(EncodeHintType.CHARACTER_SET, CHARSET); hints.put(EncodeHintType.MARGIN, 1); BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints); int width = bitMatrix.getWidth(); int height = bitMatrix.getHeight(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF); } } if (imgPath == null || "".equals(imgPath)) { return image; } // new a URL object URL url = new URL("http://shenghuoplus.oss-cn-shenzhen.aliyuncs.com/%E8%8F%9C%E5%93%81%E5%9B%BE%E7%89%87%2F779b931afa3f7910bc40b79b2cfb36aa.jpg"); // Open link HttpURLConnection conn = (HttpURLConnection)url.openConnection(); // Set the request method to "GET" conn.setRequestMethod("GET"); // response timeout time is 5 seconds conn.setConnectTimeout(5 * 1000); // Get the picture data through the input stream InputStream inStream = conn.getInputStream(); // binary image data obtained in order to obtain binary data package, having versatility byte[] data = readInputStream(inStream); // new file object to save a picture, save the default root directory of the current project File imageFile = new File("F:/play.png"); // Create output stream FileOutputStream outStream = new FileOutputStream(imageFile); //data input outStream.write(data); // close the output stream outStream.close(); // Insert Picture QRCodeUtil.insertImage(image, imageFile.getPath(), needCompress); return image; } public static byte[] readInputStream(InputStream inStream) throws Exception{ ByteArrayOutputStream outStream = new ByteArrayOutputStream(); // create a string Buffer byte[] buffer = new byte[1024]; // string length is read each time, or -1, representing the completion of reading all int len = 0; // use an input data stream read from the buffer in while( (len=inStream.read(buffer)) != -1 ){ // output buffer write data to the stream, the parameter represents the intermediate position from which to start reading, len representative of the read length outStream.write(buffer, 0, len); } // close the input stream inStream.close(); // write the data in the memory outStream byte[] b =outStream.toByteArray(); outStream.close(); return b; } private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception { File file = new File(imgPath); if (!file.exists()) { System.err.println ( "" + imgPath + "The file does not exist"!); return; } Image src = ImageIO.read(new File(imgPath)); int width = src.getWidth(null); int height = src.getHeight(null); if (needCompress) {// compression LOGO if (width > WIDTH) { width = WIDTH; } if (height > HEIGHT) { height = HEIGHT; } // todo a problem Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage (image, 0, 0, null); // the reduced sketch g.dispose (); src = image; } // insert LOGO Graphics2D graph = source.createGraphics(); int x = (QRCODE_SIZE - width) / 2; int y = (QRCODE_SIZE - height) / 2; graph.drawImage(src, x, y, width, height, null); Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); graph.setStroke(new BasicStroke(3f)); graph.draw(shape); graph.dispose(); } public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception { BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress); mkdirs(destPath); ImageIO.write(image, FORMAT_NAME, new File(destPath)); } public static BufferedImage encode(String content, String imgPath, boolean needCompress) throws Exception { BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress); return image; } public static void mkdirs(String destPath) { File file = new File(destPath); // When the folder does not exist, mkdirs will automatically create several directory different from the mkdir. (Mkdir if the parent directory does not exist it will throw an exception) if (!file.exists() && !file.isDirectory()) { file.mkdirs(); } } public static void encode(String content, String imgPath, String destPath) throws Exception { QRCodeUtil.encode(content, imgPath, destPath, false); } // method annotated /* * public static void encode(String content, String destPath, boolean * needCompress) throws Exception { QRCodeUtil.encode(content, null, destPath, * needCompress); } */ public static void encode(String content, String destPath) throws Exception { QRCodeUtil.encode(content, null, destPath, false); } public static void encode(String content, String imgPath, OutputStream output, boolean needCompress) throws Exception { BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress); ImageIO.write(image, FORMAT_NAME, output); } public static void encode(String content, OutputStream output) throws Exception { QRCodeUtil.encode(content, null, output, false); } public static String decode(File file) throws Exception { BufferedImage image; image = ImageIO.read(file); if (image == null) { return null; } BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image); BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); Result result; Hashtable hints = new Hashtable(); hints.put(DecodeHintType.CHARACTER_SET, CHARSET); result = new MultiFormatReader().decode(bitmap, hints); String resultStr = result.getText(); return resultStr; } public static String decode(String path) throws Exception { return QRCodeUtil.decode(new File(path)); } }
package com.sun.test.QRcode.AddLOGO; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import org.apache.commons.codec.binary.Base64; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.util.Date; import java.util.HashMap; import java.util.Map; /** * @Description: (two-dimensional code) * @Author: luoguohui * @Date: 2015-10-29 05:27:13 PM */ public class ZXingCode { private static final int QRCOLOR = 0xFF000000; // default is black private static final int BGWHITE = 0xFFFFFFFF; // background color public static void main(String[] args) throws WriterException { try { getLogoQRCode ( "https://www.baidu.com/", "jump to Baidu two-dimensional code"); } catch (Exception e) { e.printStackTrace (); } } /** * Generate two-dimensional code with the logo picture */ public static String getLogoQRCode(String qrUrl, String productName) { // String filePath = (javax.servlet.http.HttpServletRequest)request.getSession().getServletContext().getRealPath("/") + "resources/images/logoImages/llhlogo.png"; // filePath is the path to the two-dimensional code logo, but actually we are on a path of the project below, the path with the above, the following comments like String filePath = "C:/Users/DELL/Desktop/T.png"; //TODO String content = qrUrl; try { ZXingCode zp = new ZXingCode(); BufferedImage bim = zp.getQR_CODEBufferedImage(content, BarcodeFormat.QR_CODE, 400, 400, zp.getDecodeHintType()); return zp.addLogo_QRCode(bim, new File(filePath), new LogoConfig(), productName); } catch (Exception e) { e.printStackTrace (); } return null; } /** * Add pictures to the two-dimensional code Logo */ public String addLogo_QRCode(BufferedImage bim, File logoPic, LogoConfig logoConfig, String productName) { try { /** * Read two-dimensional code images and drawing objects to build */ BufferedImage image = bim; Graphics2D g = image.createGraphics(); /** * Read Logo Picture */ BufferedImage logo = ImageIO.read(logoPic); /** * Set the size of the logo, I set the two-dimensional code images 20%, because the General Assembly had the cover off the two-dimensional code */ int widthLogo = logo.getWidth(null) > image.getWidth() * 3 / 10 ? (image.getWidth() * 3 / 10) : logo.getWidth(null), heightLogo = logo.getHeight(null) > image.getHeight() * 3 / 10 ? (image.getHeight() * 3 / 10) : logo.getWidth(null); /** * Logo placed in the center */ int x = (image.getWidth() - widthLogo) / 2; int y = (image.getHeight() - heightLogo) / 2; /** * Logo on the bottom right corner * int x = (image.getWidth() - widthLogo); * int y = (image.getHeight() - heightLogo); */ // start drawing pictures g.drawImage(logo, x, y, widthLogo, heightLogo, null); // g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15); // g.setStroke(new BasicStroke(logoConfig.getBorder())); // g.setColor(logoConfig.getBorderColor()); // g.drawRect(x, y, widthLogo, heightLogo); g.dispose (); // add up the trade name, trade name not too long Oh, supports up to two lines here. Too long will automatically intercept it if (productName != null && !productName.equals("")) { // new image, the two-dimensional code with the following logo plus text BufferedImage outImage = new BufferedImage(400, 445, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D outg = outImage.createGraphics(); // draw two-dimensional code to the new panel outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); // draw the text to the new panel outg.setColor(Color.BLACK); outg.setFont (new Font ( "Arial", Font.BOLD, 30)); // font, font, font size int strWidth = outg.getFontMetrics().stringWidth(productName); if (strWidth > 399) { // // taken too long on the front portion // outg.drawString(productName, 0, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 5 ); //画文字 // too long to wrap String productName1 = productName.substring(0, productName.length() / 2); String productName2 = productName.substring(productName.length() / 2, productName.length()); int strWidth1 = outg.getFontMetrics().stringWidth(productName1); int strWidth2 = outg.getFontMetrics().stringWidth(productName2); outg.drawString (productName1, 200 - strWidth1 / 2, image.getHeight () + (outImage.getHeight () - image.getHeight ()) / 2 + 12); BufferedImage outImage2 = new BufferedImage(400, 485, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D outg2 = outImage2.createGraphics(); outg2.drawImage (outImage, 0, 0, outImage.getWidth () outImage.getHeight (), null); outg2.setColor(Color.BLACK); outg2.setFont (new Font ( "Arial", Font.BOLD, 30)); // font, font, font size outg2.drawString (productName2, 200 - strWidth2 / 2 outImage.getHeight () + (outImage2.getHeight () - outImage.getHeight ()) / 2 + 5); outg2.dispose (); outImage2.flush (); outImage = outImage2; } else { outg.drawString(productName, 200 - strWidth / 2, image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 12); //画文字 } outg.dispose (); outImage.flush (); image = outImage; } logo.flush(); image.flush(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); baos.flush(); ImageIO.write(image, "png", baos); // path generated two-dimensional code, but the actual project, we put the generated two-dimensional code displayed on the screen, so the following code can be wrapped commented // You can see that this method is the final return of the two-dimensional code string imageBase64 // distal end with <play src = "data: image / png; base64, $ {imageBase64QRCode}" /> where $ {imageBase64QRCode} corresponding to the two-dimensional code string imageBase64 // ImageIO.write(image, "png", new File("C:/Users/luoguohui/Desktop/TDC-" + new Date().getTime() + "test.png")); //TODO ImageIO.write(image, "png", new File("F:/" + new Date().getTime() + "test.png")); String imageBase64QRCode = Base64.encodeBase64URLSafeString(baos.toByteArray()); baos.close(); return imageBase64QRCode; } catch (Exception e) { e.printStackTrace (); } return null; } /** * Construction of two-dimensional code to initialize * * @Param bm * @return */ public BufferedImage fileToBufferedImage(BitMatrix bm) { BufferedImage image = null; try { int w = bm.getWidth(), h = bm.getHeight(); image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE); } } } catch (Exception e) { e.printStackTrace (); } return image; } /** * Generate two-dimensional code bufferedImage Pictures * * @Param content encoded content * @Param barcodeFormat encoding type * @Param width image width * @Param height Image Height * @Param hints parameter settings * @return */ public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints) { MultiFormatWriter multiFormatWriter = null; BitMatrix bm = null; BufferedImage image = null; try { multiFormatWriter = new MultiFormatWriter(); // parameters are sequence: encoding the content, coding type, generating a picture width, picture height generated, setting parameters bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints); int w = bm.getWidth(); int h = bm.getHeight(); image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); // start using the data to create two-dimensional code Bitmap images are set to black (0xFFFFFFFF) White (0xFF000000) two-color for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BGWHITE); } } } catch (WriterException e) { e.printStackTrace (); } return image; } /** * Set of two-dimensional code format parameters * * @return */ public Map<EncodeHintType, Object> getDecodeHintType() { // QR two-dimensional code is used to set parameters Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>(); // set the QR two-dimensional code error correction level (H being the highest level) information specific level hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // set the encoding hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); hints.put(EncodeHintType.MARGIN, 0); hints.put(EncodeHintType.MAX_SIZE, 350); hints.put(EncodeHintType.MIN_SIZE, 100); return hints; } } class LogoConfig { // logo default border color public static final Color DEFAULT_BORDERCOLOR = Color.WHITE; // logo default border width public static final int DEFAULT_BORDER = 2; // logo size defaults to photo 1/5 public static final int DEFAULT_LOGOPART = 5; private final int border = DEFAULT_BORDER; private final Color borderColor; private final int logoPart; /** */ public LogoConfig() { this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART); } public LogoConfig(Color borderColor, int logoPart) { this.borderColor = borderColor; this.logoPart = logoPart; } public Color getBorderColor() { return borderColor; } public int getBorder() { return border; } public int getLogoPart() { return logoPart; } }