package com.fdkankan.image;

import cn.hutool.core.io.FileUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

@Slf4j
public class MatrixToImageWriterUtil {

    private static final int BLACK = 0xFF000000;//用于设置图案的颜色
    private static final int WHITE = 0xFFFFFFFF; //用于背景色  

    private MatrixToImageWriterUtil() {}

    public static BufferedImage toBufferedImage(BitMatrix matrix) {
        int width = matrix.getWidth();
        int height = matrix.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, (matrix.get(x, y) ? BLACK : WHITE));
//              image.setRGB(x, y,  (matrix.get(x, y) ? Color.YELLOW.getRGB() : Color.CYAN.getRGB()));  
            }
        }
        return image;
    }

    public static boolean writeToFile(BitMatrix matrix, String format, File file, boolean logo, String logoPath) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        //设置logo图标  
        LogoConfig logoConfig = new LogoConfig();
        image = logoConfig.LogoMatrix(image, logo, logoPath);

        File parFile = new File(file.getParent() + File.separator);
        if (!parFile.exists()){
            parFile.mkdirs();
        }

        if (!ImageIO.write(image, format, file)) {
            //throw new IOException("Could not write an image of format " + format + " to " + file); 
            log.info("Could not write an image of format " + format + " to " + file);
            return false;
        } else {
            log.info("二维码生成成功！");
            return true;
        }
    }

    public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        //设置logo图标  
        LogoConfig logoConfig = new LogoConfig();
        image = logoConfig.LogoMatrix(image, true,null);

        if (!ImageIO.write(image, format, stream)) {
            throw new IOException("Could not write an image of format " + format);
        }
    }

    //url
    public static boolean createQRCode(String url, String outPath, boolean logo, String logoPath) throws Exception {
        // 生成二维码

        int width = 3000; // 二维码图片宽度 300
        int height = 3000; // 二维码图片高度300

        String format = "jpg";// 二维码的图片格式 gif  

        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        // 指定纠错等级,纠错级别（L 7%、M 15%、Q 25%、H 30%）
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 内容所使用字符集编码  
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
//      hints.put(EncodeHintType.MAX_SIZE, 350);//设置图片的最大值  
//      hints.put(EncodeHintType.MIN_SIZE, 100);//设置图片的最小值  
        hints.put(EncodeHintType.MARGIN, 1);//设置二维码边的空度，非负数  

        BitMatrix bitMatrix = new MultiFormatWriter().encode(url,
                //编码类型，目前zxing支持：Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,  
                //Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,  
                //MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION  
                BarcodeFormat.QR_CODE,
                width, //条形码的宽度  
                height, //条形码的高度  
                hints);//生成条形码时的一些配置,此项可选  

        //File outputFile = new File("d:" + File.separator + "new-1.gif");//指定输出路径
        File outputFile = new File(outPath);//指定输出路径
        FileUtil.del(outPath);
        return writeToFile(bitMatrix, format, outputFile, logo, logoPath);
    }

    public static void main(String[] args) throws Exception{
        MatrixToImageWriterUtil.createQRCode("https://www.4dkankan.com/spc.html?m=t-pnj0IJX", "F:\\test\\4Dkankan_share.png", true, "F:\\test\\8.jpg");
//        MatrixToImageWriterUtil.createQRCode("https://www.4dkankan.com/spc.html?m=t-pnj0IJX&lang=en", "F:/桌面/t-pnj0IJX_en.png", null);
    }
}
