package org.jeecg.modules.opencv.utils;

import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class ImageUtils {

    /**
     * 按照指定的尺寸截取Mat，坐标原点为左上角
     *
     * @param src    源Mat
     * @param width  width
     * @param height height
     * @return 截取后的Mat
     */
    public static Mat cutFromCenter(Mat src, int width, int height) {
        if (width > src.width()) {
            width = src.width();
        }
        if (height > src.height()) {
            height = src.height();
        }
        int originX = (src.width() - width) / 2;
        int originy = (src.height() - height) / 2;
        // 截取尺寸
        Rect rect = new Rect(originX, originy, width, height);
        return new Mat(src, rect);
    }

    public static Mat radialBlur(Mat src) {
        Mat returnMat = new Mat(src.size(), CvType.CV_32FC3);
        src.convertTo(returnMat, CvType.CV_32FC3);
        int width = src.width();
        int height = src.height();
        double r;
        double angle;
        Point center = new Point(width / 2, height / 2);
        double t1, t2, t3;
        int new_x, new_y;
        int Num = 20;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                t1 = 0;
                t2 = 0;
                t3 = 0;
                r = Math.sqrt((y - center.y) * (y - center.y) + (x - center.x) * (x - center.x));
                angle = Math.atan2((y - center.y), (x - center.x));
                for (int mm = 0; mm < Num; mm++) {
                    double tmR = r - mm > 0 ? r - mm : 0.0;
                    new_x = (int) (tmR * Math.cos(angle) + center.x);
                    new_y = (int) (tmR * Math.sin(angle) + center.y);
                    if (new_x < 0) {
                        new_x = 0;
                    }
                    if (new_x > width - 1) {
                        new_x = width - 1;
                    }
                    if (new_y < 0) {
                        new_y = 0;
                    }
                    if (new_y > height - 1) {
                        new_y = height - 1;
                    }
                    t1 = t1 + src.get(new_y, new_x)[0];
                    t2 = t2 + src.get(new_y, new_x)[1];
                    t3 = t3 + src.get(new_y, new_x)[2];
                }
                returnMat.put(y, x, t1 / Num, t2 / Num, t3 / Num);
            }
        }
        return returnMat;
    }

    /**
     * 矩阵横向拼接
     *
     * @param matrix1
     * @param matrix2
     * @param matrixCom
     * @return
     */
    public static Mat hconcat(Mat matrix1, Mat matrix2, Mat matrixCom) {
        matrixCom.create(matrix1.rows(), matrix1.cols() + matrix2.cols(), matrix1.type());
        Mat temp = matrixCom.colRange(0, matrix1.cols());
        matrix1.copyTo(temp);
        Mat temp1 = matrixCom.colRange(matrix1.cols(), matrix1.cols() + matrix2.cols());
        matrix2.copyTo(temp1);
        return matrixCom;
    }

    /**
     * 矩阵纵向拼接
     *
     * @param matrix1
     * @param matrix2
     * @param matrixCom
     * @return
     */
    public static Mat vconcat(Mat matrix1, Mat matrix2, Mat matrixCom) {
        matrixCom.create(matrix1.rows() + matrix2.rows(), matrix1.cols(), matrix1.type());
        Mat temp = matrixCom.rowRange(0, matrix1.rows());
        matrix1.copyTo(temp);
        Mat temp1 = matrixCom.rowRange(matrix1.rows(), matrix1.rows() + matrix2.rows());
        matrix2.copyTo(temp1);
        return matrixCom;
    }

    public static void main(String[] args) {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat image = Imgcodecs.imread("D:\\data\\167.jpg", Imgcodecs.IMREAD_COLOR);
        Mat bigImamge = new Mat();
        Mat smallImage = new Mat();
        Mat halfImage = new Mat();
        Mat wholeImage = new Mat();
        Imgproc.resize(image, bigImamge, new Size(image.cols() * 1.25, image.rows() * 1.25));
        Imgproc.resize(image, smallImage, new Size(image.cols() / 2, image.rows() / 2));
        hconcat(smallImage, smallImage, halfImage);
        vconcat(halfImage, halfImage, wholeImage);
        Mat destImage = cutFromCenter(bigImamge, image.width(), image.height());
        wholeImage = radialBlur(wholeImage);
        Mat radialBlur = radialBlur(destImage);
        Imgcodecs.imwrite("D:\\data\\radialBlur.jpg", radialBlur);
        Imgcodecs.imwrite("D:\\data\\whole.jpg", wholeImage);
    }
}
