package com.bcxin.identify.util.baidu;

import com.alibaba.fastjson.JSON;
import com.bcxin.identify.util.ObjectUtils;
import com.bcxin.identify.util.Result;
import com.bcxin.identify.util.codes.BcxColor;
import com.bcxin.identify.util.codes.CommonConst;
import com.bcxin.identify.util.common.StringUtil;
import com.bcxin.identify.util.file.BcxinFileUtils;
import com.bcxin.identify.util.sys.ConfigUtil;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 人像分割
 * @date 2019-08-20
 * @auth llc
 * @return Result
 */
public class BaiduFaceCutUtil {

    private final static String paramSeparator = "&";

    /**
     * 重要提示代码中所需工具类
     * FileUtil,Base64Util,HttpUtil,GsonUtils请从
     * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
     * https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
     * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
     * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
     * 下载
     */

    /**
     * 调用百度api获取分割后的人像前景抠图
     * @param accessToken
     * @param platform
     * @param colorStr
     * @date 2019-08-20
     * @auth llc
     * @return Result
     */
    public static String faceCut(String accessToken,String platform ,String targetImg,String colorStr) {
       String fileUrl = "";
        try {
            byte[] imgData = BaiduFileUtil.readFileByBytes(targetImg);
            String imgStr = BaiduBase64Util.encode(imgData);
            String imgParam = URLEncoder.encode(imgStr, "UTF-8");
            /*** 定义返回的文件类型 ***/
            /*** 返回文件类型  type 参数值可以是可选值的组合，用逗号分隔；如果无此参数默认输出全部3类结果图
             labelmap	分割结果图片，base64编码之后的二值图像，需二次处理方能查看分割效果
             scoremap	分割后人像前景的scoremap，归一到0-255，不用进行二次处理，直接解码保存图片即可。Base64编码后的灰度图文件，图片中每个像素点的灰度值 = 置信度 * 255，置信度为原图对应像素点位于人体轮廓内的置信度，取值范围[0, 1]
             foreground	分割后的人像前景抠图，透明背景，Base64编码后的png格式图片，不用进行二次处理，直接解码保存图片即可。将置信度大于0.5的像素抠出来，并通过image matting技术消除锯齿    ***/
            String type = "foreground";
            String param = "image=" + imgParam + paramSeparator + "type=" + type;
            /*** 调用百度接口 ***/
            String result = BaiduHttpUtil.post(ConfigUtil.getValue(CommonConst.BAIDU_GET_HAED_IMAGE_EFFECT), accessToken, param);
            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);

            if (resultMap.get("error_msg") != null && StringUtil.isNotEmpty(resultMap.get("error_msg").toString())) {

            } else {
                /*** 生成带底色的jpg图片并上传华为云 ***/
                fileUrl = getBufferedImage(resultMap.get("foreground").toString(),targetImg,platform,colorStr);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileUrl;
    }

    /**
     * 把透明的png图片转成带底色的jpg图片并上传华为云
     * @param base64String
     * @param targetImg
     * @param platform
     * @param colorStr
     * @date 2019-08-20
     * @auth llc
     * @return Result
     */
    public static String getBufferedImage(String base64String,String targetImg,String platform,String colorStr) {
        BufferedImage bufferedImage = null;
        ByteArrayInputStream stream = null;
        File file = new File(targetImg);
        String fileUrl = "";
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] bytes1 = decoder.decodeBuffer(base64String);
            stream = new ByteArrayInputStream(bytes1);
            bufferedImage = ImageIO.read(stream);
            BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(),
                    bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);

            /*** 判断生成哪种颜色底照 ***/
            Color color = Color.WHITE;
            if(StringUtil.isNotEmpty(colorStr)) {
                if (ObjectUtils.equals(colorStr, "white")) {
                    color = Color.WHITE;
                }else if (ObjectUtils.equals(colorStr, "red")) {
                    color = Color.RED;
                }else if (ObjectUtils.equals(colorStr, "blue")) {
                    color = BcxColor.CerBlue;
                }
            }
            newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, color, null);

            ImageIO.write(newBufferedImage, "jpg", file);
            /*** 上传华为云 ***/
            fileUrl = BcxinFileUtils.huaweiOBSFileUpload(file,platform, "jpg");
            /*** 传完删除本地文件 ***/
            file.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (stream != null) {
                    stream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return  fileUrl ;
    }


    /**
     * 调用百度api获取照片信息
     * @param accessToken
     * @date 2020-09-08
     * @auth llc
     * @return Result
     */
    public static Result getPhotoInfo(String accessToken, String targetImg) {
        try {
            byte[] imgData = BaiduFileUtil.readFileByBytes(targetImg);
            String imgStr = BaiduBase64Util.encode(imgData);
            String imgParam = URLEncoder.encode(imgStr, "UTF-8");
            String param = "image=" + imgParam;
            /*** 调用百度接口 ***/
            String result = BaiduHttpUtil.post(ConfigUtil.getValue(CommonConst.BAIDU_GET_PHOTO_IMAGE_INFO), accessToken, param);
            Map<String, Object> resultMap = JSON.parseObject(result, Map.class);

            if (resultMap.get("error_msg") != null && StringUtil.isNotEmpty(resultMap.get("error_msg").toString())) {
                return Result.fail("",resultMap);
            } else {
                return Result.success(Result.SUCCESS_QUERY_MSG,resultMap);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.success(Result.SUCCESS_QUERY_MSG,null);
    }


    public static void main(String[] args) {
        String accessToken = "24.d49039bad13f84adaa0d2aa6c7839201.2592000.1600503839.282335-16871051";
        String targetImg = "d:/download/123.jpg";
        Result result = getPhotoInfo(accessToken,targetImg);
        System.out.println(result);
    }
}