package com.zhgd.xmgl.modules.basicdata.api.image_ai;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.bytedeco.javacpp.Loader;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_java;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.opencv.highgui.HighGui;
import org.springframework.beans.factory.annotation.Value;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.UUID;

/**
 * opencv通过rtsp流截取图片
 */

@Slf4j
@UtilityClass
public class Opencv {

    /**
     * 生成图片地址
     */
    @Value("${opencv.filePath}")
    private String filePath;

    public static void main(String[] args) {
        createImage("rtsp://admin:jxj12345@10.0.77.104:554/Streaming/Channels/101");
    }

    public String createImage(String rtsp) {
        return createImage(rtsp, 1920, 1080);
    }
    /**
     *
     * @param rtsp       流
     * @param imageWid   生成图片宽度
     * @param imageHei   生成图片高度
     * @return
     */
    public String createImage(String rtsp, int imageWid, int imageHei) {
        if (filePath == null) {
            filePath = "D://opencv//";
        }
        log.info("==========opencv start=============");
        log.info("rtsp:" + rtsp + ";filePath: " + filePath);
        Loader.load(opencv_java.class);
        FFmpegFrameGrabber grabber = null;
        try {
            grabber = FFmpegFrameGrabber.createDefault(rtsp);
            grabber.setOption("rtsp_transport", "tcp"); // 使用tcp的方式，不然会丢包很严重
            // 一直报错的原因！！！就是因为是 2560 * 1440的太大了。。
            grabber.setImageWidth(imageWid);
            grabber.setImageHeight(imageHei);
            System.out.println("grabber start");
            grabber.start();
            OpenCVFrameConverter.ToMat converter = new OpenCVFrameConverter.ToMat();
            OpenCVFrameConverter.ToOrgOpenCvCoreMat converter1 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();
            Frame frame = grabber.grabImage();
            opencv_core.Mat mat = converter.convertToMat(frame);
            org.opencv.core.Mat cvmat = converter1.convert(converter.convert(mat));
            //上述的Mat对象
            Image image = HighGui.toBufferedImage(cvmat);
            //转换图片
            BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_3BYTE_BGR);
            Graphics g = bi.getGraphics();
            g.drawImage(image, 0, 0, null);
            //将BufferedImage变量写入临时文件中。保存到本地
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            File file = new File(filePath + uuid + ".jpg");
            ImageIO.write(bi, "jpg", file);
            mat.release();
            cvmat.release();
            log.info("==========opencv success=============");
            return filePath + uuid + ".jpg";
        } catch (Exception e) {
            log.info("==========opencv fail=============");
            throw new RuntimeException(e);
        }
    }
}
