Share a two-dimensional code generation tool api utils

We need to introduce a jar:

<!-- https://mvnrepository.com/artifact/com.google.zxing/core -->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.4.0</version>
        </dependency>

Then the tools QRCodeUtil and BufferedImageLuminanceSource:

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Hashtable;
java.util.Random import;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
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;


    /**
     * Generate two-dimensional code
     * @Param content source content
     * @Param imgPath generate two-dimensional code saved path
     * @Param needCompress whether to collapse
     * @Return returns the two-dimensional code picture
     * @throws Exception
     */
    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;
        }
        // Insert Picture
        QRCodeUtil.insertImage(image, imgPath, needCompress);
        return image;
    }

    /**
     * Insert a picture in the resulting two-dimensional code
     * @param source
     * @Param imgPath
     * @param needCompress
     * @throws Exception
     */
    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;
            }
            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();
    }

    /**
     * Generate two-dimensional code with a logo, and save it to disk
     * @param content
     * @Param imgPath logo picture
     * @Param destPath
     * @param needCompress
     * @throws Exception
     */

    /**
     * Generate two-dimensional code with a logo, and save it to disk
     *
     * @param content
     * @Param imgPath logo picture
     * @Param destPath
     * @Param whether needCompress compression
     * @throws Exception
     * @author lifq
     *
     * December 13, 2016 9:54:49 AM
     */
    public static File encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
        BufferedImage image = QRCodeUtil.createImage(content, imgPath, needCompress);
        mkdirs(destPath);
        String fileName = new Random () nextInt (99999999) + ".jpg";. // generate a random file name
        File imgFile = new File(destPath + "/" + fileName);
        ImageIO.write(image, FORMAT_NAME, imgFile);
        return imgFile;
    }

    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();
        }
    }
    /**
     * Generate two-dimensional code and save it to disk directory
     *
     * @author lifq
     *
     * December 13, 2016 9:56:42 AM
     */
    public static File encode(String content, String imgPath, String destPath) throws Exception {
        return QRCodeUtil.encode(content, imgPath, destPath, false);
    }
    /**
     * Generate two-dimensional code and save it to disk directory
     *
     * @author lifq
     *
     * December 13, 2016 9:56:42 AM
     */
    public static File encode(String content, String destPath, boolean needCompress) throws Exception {
        return QRCodeUtil.encode(content, null, destPath, needCompress);
    }

    /**
     * Generate two-dimensional code and save it to disk directory
     *
     * @author lifq
     *
     * December 13, 2016 9:56:42 AM
     */
    public static File encode(String content, String destPath) throws Exception {
        return 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);
    }


    /**
     * From two-dimensional code, parsing data
     * @Param file two-dimensional code image files
     * @Return Returns parsed from the two-dimensional code to the data value
     * @throws Exception
     */
    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));
    }

    public static void main(String[] args) throws Exception {
        String text = "http://www.baidu.com";
        File file = QRCodeUtil.encode(text, "E:/data/1.jpg", true);
        System.out.println ( "generate two-dimensional code name:" + file.getName ());

        String res = QRCodeUtil.decode(file);
        System.out.println ( "two-dimensional code parsed content:" + res);
    }

}

  

import com.google.zxing.LuminanceSource;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;

/**
 * The purpose of such a hierarchy is different bitmap LuminanceSource cross-platform standard interface to request the luminance gradation value. This interface provides an abstract method,
 * It can generate and rotated to create a copy. This is to ensure that a reader does not modify the original source brightness, and have it in an unknown state, other readers in the chain.
 * https://zxing.github.io/zxing/apidocs/com/google/zxing/LuminanceSource.html
 * @author ljheee
 *
 */
public class BufferedImageLuminanceSource extends LuminanceSource {

    private final BufferedImage image;
    private final int left;
    private final int top;

    public BufferedImageLuminanceSource(BufferedImage image) {
        this(image, 0, 0, image.getWidth(), image.getHeight());
    }

    /**
     * Construction method
     * @param image
     * @param left
     * @param top
     * @param width
     * @param height
     */
    public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height) {
        super(width, height);

        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();
        if (left + width > sourceWidth || top + height > sourceHeight) {
            throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
        }

        for (int y = top; y < top + height; y++) {
            for (int x = left; x < left + width; x++) {
                if ((image.getRGB(x, y) & 0xFF000000) == 0) {
                    image.setRGB(x, y, 0xFFFFFFFF); // = white
                }
            }
        }

        this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);
        this.image.getGraphics().drawImage(image, 0, 0, null);
        this.left = left;
        this.top = top;
    }


    @Override
    public byte [] getRow (int y, byte [] row) {// extract a row (only one row) from the bitmap data of the luminance values ​​of the underlying platform
        if (y < 0 || y >= getHeight()) {
            throw new IllegalArgumentException("Requested row is outside the image: " + y);
        }
        int width = getWidth();
        if (row == null || row.length < width) {
            row = new byte[width];
        }
        image.getRaster().getDataElements(left, top + y, width, 1, row);
        return row;
    }

    @Override
    public byte [] getMatrix () {/// extract luminance data from the bit value of the underlying platform of FIG.
        int width = getWidth();
        int height = getHeight();
        int area = width * height;
        byte[] matrix = new byte[area];
        image.getRaster().getDataElements(left, top, width, height, matrix);
        return matrix;
    }

    @Override
    public boolean isCropSupported () {// whether to support cutting
        return true;
    }

    /**
     * Returns the image data of a new object and cut. Implementation can save a reference to the original data, instead of copying.
     */
    @Override
    public LuminanceSource crop(int left, int top, int width, int height) {
        return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
    }

    @Override
    public boolean isRotateSupported () {// support rotation
        return true;
    }

    @Override
    public LuminanceSource rotateCounterClockwise () {// the image data is rotated counterclockwise by 90 degrees, a new object is returned.
        int sourceWidth = image.getWidth();
        int sourceHeight = image.getHeight();
        AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);
        BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
        Graphics2D g = rotatedImage.createGraphics();
        g.drawImage(image, transform, null);
        g.dispose ();
        int width = getWidth();
        return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
    }
}

Tape test.

 

Guess you like

Origin www.cnblogs.com/ka-bu-qi-nuo/p/11790556.html
Recommended