package com.siwei.common.core.utils.file;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.GpsDirectory;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 图片处理工具类
 *
 * @author siwei-zhx
 */
public class ImageUtils {
    private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);

    public static byte[] getImage(String imagePath) {
        InputStream is = getFile(imagePath);
        try {
            return IOUtils.toByteArray(is);
        } catch (Exception e) {
            log.error("图片加载异常 {}", e);
            return null;
        } finally {
            IOUtils.closeQuietly(is);
        }
    }

    public static InputStream getFile(String imagePath) {
        try {
            byte[] result = readFile(imagePath);
            result = Arrays.copyOf(result, result.length);
            return new ByteArrayInputStream(result);
        } catch (Exception e) {
            log.error("获取图片异常 {}", e);
        }
        return null;
    }

    /**
     * 读取文件为字节数据
     *
     * @param url 地址
     * @return 字节数据
     */
    public static byte[] readFile(String url) {
        InputStream in = null;
        try {
            // 网络地址
            URL urlObj = new URL(url);
            URLConnection urlConnection = urlObj.openConnection();
            urlConnection.setConnectTimeout(30 * 1000);
            urlConnection.setReadTimeout(60 * 1000);
            urlConnection.setDoInput(true);
            in = urlConnection.getInputStream();
            return IOUtils.toByteArray(in);
        } catch (Exception e) {
            log.error("访问文件异常 {}", e);
            return null;
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * 读取图片的Gps信息
     * <pre>
     * 使用下面方式读取gps信息
     * gpsDirectory.getDescription(GpsDirectory.TAG_IMG_DIRECTION)
     *
     * TAG_IMG_DIRECTION 类型有下面这些
     * </pre>
     * <pre>
     * 基本信息
     * TAG_VERSION_ID（值为 0）：GPS 版本号，标识 GPS 数据遵循的版本规范。
     * TAG_MAP_DATUM（值为 18）：地图基准，指定用于表示经纬度的地理坐标系统，例如 WGS84 等。
     * TAG_PROCESSING_METHOD（值为 27）：GPS 处理方法，记录获取 GPS 数据所使用的处理算法或方法。
     * TAG_AREA_INFORMATION（值为 28）：区域信息，可能包含拍摄地点所在的区域名称、地理特征等描述。
     * TAG_DATE_STAMP（值为 29）：GPS 日期戳，记录 GPS 数据采集的日期。
     * TAG_DIFFERENTIAL（值为 30）：差分 GPS 信息，指示是否使用了差分 GPS 技术来提高定位精度。
     * TAG_H_POSITIONING_ERROR（值为 31）：水平定位误差，表示 GPS 定位在水平方向上的误差范围。
     * 位置信息
     * TAG_LATITUDE_REF（值为 1）：纬度参考，指示纬度是北纬（N）还是南纬（S）。
     * TAG_LATITUDE（值为 2）：纬度值，通常以度、分、秒的形式存储，可通过相应方法转换为十进制度数。
     * TAG_LONGITUDE_REF（值为 3）：经度参考，指示经度是东经（E）还是西经（W）。
     * TAG_LONGITUDE（值为 4）：经度值，同样以度、分、秒的形式存储，可转换为十进制度数。
     * TAG_ALTITUDE_REF（值为 5）：海拔参考，指示海拔是高于还是低于海平面。
     * TAG_ALTITUDE（值为 6）：海拔高度，单位通常为米。
     * TAG_DEST_LATITUDE_REF（值为 19）：目标纬度参考，用于指示目标位置的纬度是北纬还是南纬。
     * TAG_DEST_LATITUDE（值为 20）：目标纬度值。
     * TAG_DEST_LONGITUDE_REF（值为 21）：目标经度参考，指示目标位置的经度是东经还是西经。
     * TAG_DEST_LONGITUDE（值为 22）：目标经度值。
     * 时间和卫星信息
     * TAG_TIME_STAMP（值为 7）：GPS 时间戳，记录 GPS 数据采集的具体时间。
     * TAG_SATELLITES（值为 8）：参与定位的卫星数量或卫星编号信息。
     * 状态和测量信息
     * TAG_STATUS（值为 9）：GPS 状态，例如是否正在接收信号、定位是否成功等。
     * TAG_MEASURE_MODE（值为 10）：测量模式，如二维定位、三维定位等。
     * TAG_DOP（值为 11）：精度因子，反映 GPS 定位的精度，包括水平精度因子（HDOP）、垂直精度因子（VDOP）等。
     * 速度和方向信息
     * TAG_SPEED_REF（值为 12）：速度参考单位，如节（海里 / 小时）、公里 / 小时等。
     * TAG_SPEED（值为 13）：移动速度，根据参考单位表示的移动速度值。
     * TAG_TRACK_REF（值为 14）：移动方向参考，指示移动方向是相对于真北还是磁北。
     * TAG_TRACK（值为 15）：移动方向角度，相对于参考方向的移动角度。
     * TAG_IMG_DIRECTION_REF（值为 16）：图片拍摄方向参考，指示拍摄方向是相对于真北还是磁北。
     * TAG_IMG_DIRECTION（值为 17）：图片拍摄方向角度，相对于参考方向的拍摄角度。
     * TAG_DEST_BEARING_REF（值为 23）：目标方位参考，指示目标方位是相对于真北还是磁北。
     * TAG_DEST_BEARING（值为 24）：目标方位角度，相对于参考方向的目标方位角度。
     * TAG_DEST_DISTANCE_REF（值为 25）：目标距离参考单位，如米、公里等。
     * TAG_DEST_DISTANCE（值为 26）：到目标的距离，根据参考单位表示的距离值
     *
     * </pre>
     *
     * @param imageFile 地址
     * @return Gps信息
     */
    public static GpsDirectory readFileGps(File imageFile) {
        try {
            // 读取图片元数据
            Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
            // 读取坐标点（经纬度）
            GpsDirectory gpsDirectory = metadata.getFirstDirectoryOfType(GpsDirectory.class);
            return gpsDirectory;
        } catch (Exception e) {
            log.error("访问文件异常 {}", e);
            return null;
        }
    }

    /**
     * 读取图片的Gps信息
     *
     * @param imageFile 地址
     * @return Gps信息
     */
    public static GpsDirectory readFileGps(String imageFile) {
        return readFileGps(new File(imageFile));
    }

    /**
     * 读取图片的Metadata信息(元数据)
     *
     * @param imageFile 地址
     * @return Gps信息
     */
    public static Metadata readFileMetadata(String imageFile) {
        return readFileMetadata(new File(imageFile));
    }

    /**
     * 读取图片的Metadata信息(元数据)
     *
     * @param imageFile 地址
     * @return Gps信息
     */
    public static Metadata readFileMetadata(File imageFile) {
        try {
            // 读取图片元数据
            Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
            return metadata;
        } catch (Exception e) {
            log.error("访问文件异常 {}", e);
            return null;
        }
    }

}
