package com.schisandra.auth.common.utils;

import java.util.Base64;
import java.util.Base64.Encoder;
import java.util.Base64.Decoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class RotateImageUtils {

    public static Color bgColor = new Color(255, 255, 255);


    /**
     * @description: 压缩图片并将图片转换成base64
     * @param: [bufferedImage]
     * @return: java.lang.String
     * @author zlg
     * @date: 2024/5/9 13:13
     */
    public static String BufferedImageToBase64(BufferedImage bufferedImage) throws IOException {
        int targetWidth = 400;
        int targetHeight = 400;
        // 获取原始图片的尺寸
        int originalWidth = bufferedImage.getWidth();
        int originalHeight = bufferedImage.getHeight();
        // 创建一个新的 BufferedImage，用于存放处理后的图片
        BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, bufferedImage.getType());
        // 创建一个 Graphics2D 对象，用于绘制新图片
        Graphics2D graphics = outputImage.createGraphics();
        // 如果原始图片尺寸大于目标尺寸，则进行压缩
        if (originalWidth > targetWidth || originalHeight > targetHeight) {
            Image scaledImage = bufferedImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);
            graphics.drawImage(scaledImage, 0, 0, null);
        }
        graphics.dispose();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
        ImageIO.write(outputImage, "png", baos);//写入流中
        byte[] bytes = baos.toByteArray();//转换成字节
        Encoder encoder = Base64.getEncoder();
        String png_base64 = encoder.encodeToString(bytes);//转换成base64串
        png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
        return "data:image/jpg;base64," + png_base64;

    }

    /**
     * @description: 将base64转换成图片
     * @param: [base64]
     * @return: java.awt.image.BufferedImage
     * @author zlg
     * @date: 2024/5/9 13:14
     */
    public static BufferedImage base64ToBufferedImage(String base64) {
        Decoder decoder = Base64.getDecoder();
        try {
            byte[] bytes1 = decoder.decode(base64);
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes1);
            return ImageIO.read(bais);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @description: 获取旋转后的图片
     * @param: [image, theta, backgroundColor]
     * @return: java.awt.image.BufferedImage
     * @author zlg
     * @date: 2024/5/9 13:14
     */
    public BufferedImage rotateImage(BufferedImage image, double theta) {
        int width = image.getWidth();
        int height = image.getHeight();
        double angle = theta * Math.PI / 180; // 度转弧度
        double[] xCoords = getX(width / 2, height / 2, angle);
        double[] yCoords = getY(width / 2, height / 2, angle);
        int WIDTH = (int) (xCoords[3] - xCoords[0]);
        int HEIGHT = (int) (yCoords[3] - yCoords[0]);
        BufferedImage resultImage = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        for (int i = 0; i < WIDTH; i++) {
            for (int j = 0; j < HEIGHT; j++) {
                int x = i - WIDTH / 2;
                int y = HEIGHT / 2 - j;
                double radius = Math.sqrt(x * x + y * y);
                double angle1;
                if (y > 0) {
                    angle1 = Math.acos(x / radius);
                } else {
                    angle1 = 2 * Math.PI - Math.acos(x / radius);
                }
                x = (int) Math.round(radius * Math.cos(angle1 - angle));
                y = (int) Math.round(radius * Math.sin(angle1 - angle));
                if (x < (width / 2) & x > -(width / 2) & y < (height / 2) & y > -(height / 2)) {
                    int rgb = image.getRGB((int) Math.round(x + width / 2), (int) Math.round(height / 2 - y));
                    resultImage.setRGB(i, j, rgb);
                } else {
                    resultImage.setRGB(i, j, -1);
                }
            }
        }
        return resultImage;
    }

    // 获取四个角点旋转后Y方向坐标
    private double[] getY(int i, int j, double angle) {
        double results[] = new double[4];
        double radius = Math.sqrt(i * i + j * j);
        double angle1 = Math.asin(j / radius);
        results[0] = radius * Math.sin(angle1 + angle);
        results[1] = radius * Math.sin(Math.PI - angle1 + angle);
        results[2] = -results[0];
        results[3] = -results[1];
        Arrays.sort(results);
        return results;
    }

    // 获取四个角点旋转后X方向坐标
    private double[] getX(int i, int j, double angle) {
        double results[] = new double[4];
        double radius = Math.sqrt(i * i + j * j);
        double angle1 = Math.acos(i / radius);
        results[0] = radius * Math.cos(angle1 + angle);
        results[1] = radius * Math.cos(Math.PI - angle1 + angle);
        results[2] = -results[0];
        results[3] = -results[1];
        Arrays.sort(results);
        return results;
    }

    /**
     * @description: 获取旋转后的图片
     * @param: [image]
     * @return: java.awt.image.BufferedImage
     * @author zlg
     * @date: 2024/5/9 13:14
     */
    public BufferedImage writeCyclePic(BufferedImage image) {
        BufferedImage newImage = new BufferedImage(350, 350, BufferedImage.TYPE_INT_BGR);
        try {
            int width = image.getWidth();
            int heigth = image.getHeight();
            double x0 = width / 2;
            double y0 = heigth / 2;
            int woffset = (width - 350) / 2;
            int hoffset = (heigth - 350) / 2;
            for (int i = woffset; i < 350 + woffset; i++) {
                for (int j = hoffset; j < 350 + hoffset; j++) {
                    double r = Math.sqrt(Math.pow(Math.abs(i - x0), 2.0) + Math.pow(Math.abs(j - y0), 2.0));
                    if (r > (x0 - woffset)) {
                        newImage.setRGB(i - woffset, j - hoffset, -1);
                    } else {
                        newImage.setRGB(i - woffset, j - hoffset, image.getRGB(i, j));
                    }
                }
            }
            return newImage;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }




}
