ke
2024-05-13 d31e928394ad711a86a3d93caa6470b1abb96a39
全景图更新切图功能kl  5-13
7 files modified
11 files added
1902 ■■■■■ changed files
skjcmanager/skjcmanager-ops-api/skjcmanager-resource-api/src/main/java/cn/gistack/resource/entity/QieTuEntity.java 15 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops-api/skjcmanager-resource-api/src/main/java/cn/gistack/resource/feign/IOssClient.java 38 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops-api/skjcmanager-resource-api/src/main/java/cn/gistack/resource/feign/IOssClientFallback.java 29 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/pom.xml 7 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/builder/oss/OssBuilder.java 33 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/endpoint/OssEndpoint.java 126 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/feign/OssClient.java 82 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/FileTestUtils.java 35 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/Img4JavaUtil.java 433 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/OSinfo.java 161 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/QietuResult.java 49 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/rule/PanoramaOSSRule.java 50 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/pom.xml 11 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/controller/SkPanoramaController.java 185 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/entity/SkPanoramaEntity.java 27 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/mapper/SkPanoramaMapper.xml 22 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/utils/Img4JavaUtil.java 438 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/utils/OSinfo.java 161 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-ops-api/skjcmanager-resource-api/src/main/java/cn/gistack/resource/entity/QieTuEntity.java
New file
@@ -0,0 +1,15 @@
package cn.gistack.resource.entity;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
@Data
public class QieTuEntity {
    private HashMap<String,String> qietuHashMap;
    private String resGuid;
}
skjcmanager/skjcmanager-ops-api/skjcmanager-resource-api/src/main/java/cn/gistack/resource/feign/IOssClient.java
New file
@@ -0,0 +1,38 @@
package cn.gistack.resource.feign;
import cn.gistack.resource.entity.QieTuEntity;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.core.sms.model.SmsResponse;
import org.springblade.core.tool.api.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
/**
 * IOssClient
 *
 * @author kelu
 */
@FeignClient(
    value = AppConstant.APPLICATION_RESOURCE_NAME,
    fallback = IOssClientFallback.class
)
public interface IOssClient {
    String API_PREFIX = "/client";
    String UPLOAD_QIETU = API_PREFIX + "/upload-qietu";
    @PostMapping(UPLOAD_QIETU)
    R uploadQietu(@RequestBody QieTuEntity qieTuEntity) throws IOException;
//    @PostMapping(UPLOAD_QIETU)
//    R uploadQietu(
//        @RequestParam("qietuHashMap") HashMap<String,String> qietuHashMap
//        ,@RequestParam("resGuid")String resGuid
//        ) throws IOException;
}
skjcmanager/skjcmanager-ops-api/skjcmanager-resource-api/src/main/java/cn/gistack/resource/feign/IOssClientFallback.java
New file
@@ -0,0 +1,29 @@
package cn.gistack.resource.feign;
import cn.gistack.resource.entity.QieTuEntity;
import org.springblade.core.tool.api.R;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
/**
 * 流程远程调用失败处理类
 *
 * @author kelu
 */
@Component
public class IOssClientFallback implements IOssClient{
    @Override
    public R uploadQietu(QieTuEntity qieTuEntity) throws IOException {
        return R.fail("切图上传,远程调用失败");
    }
//    public R uploadQietu(HashMap<String,String> qietuHashMap,String resGuid) {
//        return R.fail("远程调用失败");
//    }
}
skjcmanager/skjcmanager-ops/skjcmanager-resource/pom.xml
@@ -83,6 +83,13 @@
            <artifactId>skjcmanager-dict-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <!-- ImageMagick切图 -->
        <dependency>
            <groupId>org.im4java</groupId>
            <artifactId>im4java</artifactId>
            <version>1.4.0</version>
        </dependency>
    </dependencies>
    <build>
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/builder/oss/OssBuilder.java
@@ -17,6 +17,7 @@
package cn.gistack.resource.builder.oss;
import cn.gistack.resource.rule.MyOssRule;
import cn.gistack.resource.rule.PanoramaOSSRule;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.core.cache.utils.CacheUtil;
@@ -86,6 +87,12 @@
        return templateByPath(StringPool.EMPTY,prefixPath);
    }
    public OssTemplate templateByPrefixPathPanorama(String prefixPath ,String resGuid) {
        return templateByPathPanorama(StringPool.EMPTY,prefixPath,resGuid);
    }
    /**
     * 获取template
     *
@@ -155,6 +162,32 @@
    }
    /**
     * 全景图片上传
     * @param code
     * @param prefixPath
     * @return
     */
    public OssTemplate templateByPathPanorama(String code,String prefixPath,String resGuid) {
        String tenantId = AuthUtil.getTenantId();
        Oss oss = getOss(tenantId, code);
        OssTemplate template = null;
//        template = templatePool.get(tenantId);
        OssRule ossRule = new PanoramaOSSRule(Boolean.FALSE,prefixPath,resGuid);
        if (oss.getCategory() == OssEnum.MINIO.getCategory()) {
            template = MinioOssBuilder.template(oss, ossRule);
        } else if (oss.getCategory() == OssEnum.QINIU.getCategory()) {
            template = QiniuOssBuilder.template(oss, ossRule);
        } else if (oss.getCategory() == OssEnum.ALI.getCategory()) {
            template = AliOssBuilder.template(oss, ossRule);
        } else if (oss.getCategory() == OssEnum.TENCENT.getCategory()) {
            template = TencentOssBuilder.template(oss, ossRule);
        }
//        templatePool.put(tenantId, template);
//        ossPool.put(tenantId, oss);
        return template;
    }
    /**
     * 获取对象存储实体
     *
     * @param tenantId 租户ID
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/endpoint/OssEndpoint.java
@@ -18,11 +18,14 @@
import cn.gistack.resource.builder.oss.OssBuilder;
import cn.gistack.resource.entity.TextualResearchAttach;
import cn.gistack.resource.panoramaUtils.Img4JavaUtil;
import cn.gistack.resource.panoramaUtils.QietuResult;
import cn.gistack.resource.service.IAttachService;
import cn.gistack.resource.service.TextualResearchAttachService;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.oss.model.OssFile;
import org.springblade.core.secure.annotation.PreAuth;
@@ -35,6 +38,10 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
/**
@@ -204,6 +211,123 @@
    }
    /**
     * 全景图片上传,并切图
     * @param multipartFile 文件
     * @param resGuid 水库编号
     * @return
     */
    @SneakyThrows
    @PostMapping("/put-file-by-panorama")
    public R putFileByPanorama(@RequestParam MultipartFile multipartFile, String resGuid) {
        // 临时文件路径
        String  linShiBaseUrl = "/data/panorama/qietu/";
//        String fileName = multipartFile.getOriginalFilename();
        // 获取文件名
        String picName = multipartFile.getOriginalFilename();// 原始全景图名称
        String dirPath = linShiBaseUrl + resGuid + "/"; //临时文件夹路径
        File dir = new File(dirPath);
        if (dir.isDirectory()) {
            // 清除该目录下的文件及子目录文件而不删除该目录文件夹。该目录不存在会报错
            FileUtils.cleanDirectory(dir);
        } else {
            dir.mkdirs();
        }
        String picUrl = dirPath + picName; // 原始全景图文件路径
        File file = new File(picUrl); // 文件上传的原始全景图,存入临时路径
        multipartFile.transferTo(file);
        FileInputStream ysfileInputStream = new FileInputStream(file);
        BladeFile qjbladeFile = ossBuilder.templateByPrefixPathPanorama("panorama", resGuid).putFile(picName, ysfileInputStream);
        String yuanshiQJurl = qjbladeFile.getLink();
        ysfileInputStream.close();
        /**
         * 这里开始切图
         */
        HashMap<String,String> qietuHashMap = new HashMap<String,String>();
        int col = 8;
        int row = 4;
        String[] split = picName.split("\\.");
        String picHeadName = split[0];
        String picLastName = split[1];
        // 获取原始全景图图片信息
        HashMap<String, Integer> imgInfoRT = Img4JavaUtil.getImgInfoRT(file);
        Integer width = imgInfoRT.get("width");
        Integer height = imgInfoRT.get("height");
        // 计算切成小图的长和宽
        Integer biliWidth = width/col;
        Integer biliHeight = height/row;
        for (int i=0 ; i < col ; i++) {
            // 计算图片的横坐标(长边)
            int x = i * biliWidth;
            for (int j=0 ; j<row ; j++){
                // 计算图片的纵坐标(宽边)
                int  y = j * biliHeight;
                // 切图名称
                String outpicName = picHeadName + "_" + i + "_" +j + "." + picLastName;
                // 切图后临时图片的的路径
                String lastiUrl = dirPath + outpicName;
                Img4JavaUtil.cropImg(picUrl ,lastiUrl ,biliWidth,biliHeight,x,y);// 切图存放进临时图片中
                qietuHashMap.put(outpicName,lastiUrl);
            }
        }
        // 切图完成后删除原始全景图
        if (file.exists()) {
            // 删除指定文件,不存在报异常
            FileUtils.forceDelete(file);
        }
        /************************************切图结束********************************************/
        List<String> qieTuUrlList = new ArrayList<String>();
        String urlHead = null;
        Set<String> mapKey = qietuHashMap.keySet();
        if(qietuHashMap != null && qietuHashMap.size()>0) {
            for (String picQName : mapKey) {
                String url = qietuHashMap.get(picQName);
                Path qietuPath = Paths.get(url);
                File qietufile = qietuPath.toFile();
                FileInputStream fileInputStream = new FileInputStream(qietufile);
                BladeFile bladeFile = ossBuilder.templateByPrefixPathPanorama("panorama", resGuid).putFile(picQName, fileInputStream);
                fileInputStream.close(); // 关闭文件流
                // 切图上传完成后删除
                if (qietufile.exists()) {
                    // 删除指定文件,不存在报异常
                    FileUtils.forceDelete(qietufile);
                }
                String link = bladeFile.getLink();
                qieTuUrlList.add(link);// 上传后的图片路径
                urlHead = link.replace(picQName,"");
            }
        }
        QietuResult qietuResult = new QietuResult();
        qietuResult.setQieTuUrlList(qieTuUrlList);
        qietuResult.setUrlHead(urlHead);
        qietuResult.setRow(row);
        qietuResult.setCol(col);
        qietuResult.setQuanJingWidth(width);
        qietuResult.setQuanJingHeight(height);
        qietuResult.setQjName(picName);
        qietuResult.setQjUrl(yuanshiQJurl);
        return R.data(qietuResult) ;
    }
    @SneakyThrows
    @PostMapping("/put-file-by-panorama2")
    public R putFileByPanorama2(@RequestParam MultipartFile multipartFile, String resGuid){
        return null;
    }
    /**
     * 保存考证附件上传数据
     * @param bladeFile
     */
@@ -248,6 +372,8 @@
        return R.data(bladeFile);
    }
    /**
     * 上传文件并保存至附件表
     *
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/feign/OssClient.java
New file
@@ -0,0 +1,82 @@
package cn.gistack.resource.feign;
import cn.gistack.resource.builder.oss.OssBuilder;
import cn.gistack.resource.entity.QieTuEntity;
import cn.gistack.resource.panoramaUtils.QietuResult;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
/**
 * @author kelu
 */
@NonDS
@RestController
@AllArgsConstructor
public class OssClient implements IOssClient{
    /**
     * 对象存储构建类
     */
    private final OssBuilder ossBuilder;
    @Override
    @PostMapping(UPLOAD_QIETU)
    public R uploadQietu(QieTuEntity qieTuEntity) throws IOException {
//    public R uploadQietu(HashMap<String,String> qietuHashMap,String resGuid) throws IOException {
        HashMap<String,String> qietuHashMap = qieTuEntity.getQietuHashMap();
        String resGuid = qieTuEntity.getResGuid();
        List<String> qieTuUrlList = new ArrayList<String>();
        String urlHead = null;
        Set<String> mapKey = qietuHashMap.keySet();
        if(qietuHashMap != null && qietuHashMap.size()>0) {
            for (String picQName : mapKey) {
                String url = qietuHashMap.get(picQName);
                Path qietuPath = Paths.get(url);
                File qietufile = qietuPath.toFile();
                FileInputStream fileInputStream = new FileInputStream(qietufile);
                BladeFile bladeFile = ossBuilder.templateByPrefixPathPanorama("panorama", resGuid).putFile(picQName, fileInputStream);
                fileInputStream.close(); // 关闭文件流
                String link = bladeFile.getLink();
                qieTuUrlList.add(link);// 上传后的图片路径
                urlHead = link.replace(picQName,"");
                // 切图上传完成后删除
                if (qietufile.exists()) {
                    // 删除指定文件,不存在报异常
                    FileUtils.forceDelete(qietufile);
                }
            }
        }
        String jsonString = JSON.toJSONString(qieTuUrlList);
        HashMap<String, String> stringStringHashMap = new HashMap<>();
        stringStringHashMap.put("qturlList",jsonString);
        stringStringHashMap.put("urlHead", urlHead);
        QieTuEntity result = new QieTuEntity();
        result.setQietuHashMap(stringStringHashMap);
        return R.data(result);
    }
}
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/FileTestUtils.java
New file
@@ -0,0 +1,35 @@
package cn.gistack.resource.panoramaUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
/**
 * @author kelu
 */
public class FileTestUtils {
    /**
     * MultipartFile 转 IO File
     * @param multipartFile
     * @return
     */
    public static File multiPartFileToFile3(MultipartFile multipartFile) {
        File file = null;
        if (multipartFile.isEmpty()) {
            return null;
        }
        try {
            //本质上还是在项目根路径创建文件
            file = new File(multipartFile.getOriginalFilename());
            //将MultipartFile的byte[]写入到file中
            FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }
}
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/Img4JavaUtil.java
New file
@@ -0,0 +1,433 @@
package cn.gistack.resource.panoramaUtils;
import org.im4java.core.*;
import org.im4java.process.ProcessStarter;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
/**
 * @author kelu
 */
public class Img4JavaUtil {
    static {
        //判断是否是windows系统
        if(OSinfo.isWindows()) {
            System.out.println("------------ START 初始化ImageMagickPath -------------");
            ProcessStarter.setGlobalSearchPath("D:/im4java/ImageMagick-7.1.1-Q16-HDRI");
            System.out.println("------------ END 初始化ImageMagickPath -------------");
        } else if (OSinfo.isLinux()) {
            System.out.println("------------ START 初始化ImageMagickPath -------------");
//            ProcessStarter.setGlobalSearchPath("D:/im4java/ImageMagick-7.1.1-Q16-HDRI");
            System.out.println("------------ END 初始化ImageMagickPath -------------");
        }
    }
    /**
     * 裁剪图片
     * @param inImgPath 源图片地址
     * @param outImgPath 目标图片地址
     * @param width 宽
     * @param height 高
     * @param x 起点横坐标
     * @param y 起点纵坐标
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void cropImg(String inImgPath,String outImgPath,Integer width,Integer height,Integer x,Integer y)
        throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //宽  高 起点横坐标 起点纵坐标
        operation.crop(width, height, x, y);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 裁剪图片
     * @param inImgPath 源图片地址
     * @param outImgPath 目标图片地址
     * @param width 宽
     * @param height 高
     * @param x 起点横坐标
     * @param y 起点纵坐标
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
//    public void cropImg(String inImgPath,String outImgPath,Integer width,Integer height,Integer x,Integer y)
//        throws IOException, InterruptedException, IM4JavaException{
//        ConvertCmd cmd = new ConvertCmd();
//        IMOperation operation = new IMOperation();
//        operation.addImage(inImgPath);
//        //宽  高 起点横坐标 起点纵坐标
//        operation.crop(width, height, x, y);
//        operation.addImage(outImgPath);
//        cmd.run(operation);
//    }
    /**
     * 裁剪中心化图片
     * @param inImgPath 源图片地址
     * @param outImgPath 目标图片地址
     * @param width 宽
     * @param height 高
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void cropCenterImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        Info info = new Info(inImgPath);
        Integer init_width = info.getImageWidth();
        Integer init_height = info.getImageHeight();
        // 如果裁剪的宽高都大于原始图片宽高 则先等比放大再裁剪
        if(width>init_width || height>init_height){
            // 等比放大
            Integer temp_width = width;
            if(init_height<init_width){
                // 如果原图宽大于高 则以高为准放大
                temp_width = null;
            }
            operation.resize(temp_width, height);
        }
        operation.addImage(inImgPath);
        //宽  高 起点横坐标 起点纵坐标
        operation.gravity("center");
        operation.crop(width, height, 0, 0);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 得到图片的信息
     * @throws InfoException
     */
    public static String getImgInfo(String inImgPath) throws InfoException{
        Info info = new Info(inImgPath);
//        System.out.println(info.getImageHeight());
//        System.out.println(info.getImageWidth());
        return info.getImageWidth()+"x"+info.getImageHeight();
    }
    /**
     * 得到图片的信息
     * @throws InfoException
     */
    public static HashMap<String,Integer> getImgInfoRT( File imageFile) throws  IOException {
        HashMap stringHashMap = new HashMap<String,Integer>();
        try {
            ImageInputStream imageInputStream = ImageIO.createImageInputStream(imageFile);
            final Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream);
            if(readers.hasNext()){
                ImageReader reader = readers.next();
                reader.setInput(imageInputStream,true);
                int width = reader.getWidth(0);
                int height = reader.getHeight(0);
                stringHashMap.put("width",width);
                stringHashMap.put("height",height);
                imageInputStream.close();
            }
        } catch (IOException e) {
            System.err.println("IOException "+e.getMessage());
        }
        return stringHashMap;
    }
    /**
     * 等比缩放图片
     * @param inImgPath
     * @param outImgPath
     * @param width 宽度不为空时 以宽度为准,为空时以高度为准(不能同时为空)
     * @param height
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void resizeImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //等比缩放图片
        operation.resize(width, height);//高度为null则按宽度缩放
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 等比缩放   (使用像素平均缩小)
     * @param inImgPath
     * @param outImgPath
     * @param width
     * @param height
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void scaleImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //缩略图
        operation.scale(width,height);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 把原图裁剪成正方形
     * @param inImgPath
     * @param operation
     * @return
     * @throws IM4JavaException
     */
    public static IMOperation getCenterSquare(String inImgPath,IMOperation operation)throws IM4JavaException{
        Info info = new Info(inImgPath);
        Integer init_width = info.getImageWidth();
        Integer init_height = info.getImageHeight();
        if (init_width > init_height) {
            init_width = init_height;
        } else if (init_width < init_height) {
            init_height = init_width;
        }
        operation.gravity("center");
        operation.crop(init_width, init_height,0,0);
        return operation;
    }
    /**
     * 缩略图 (专门用于将非常大的图像缩小为小缩略图)
     * @param inImgPath
     * @param outImgPath
     * @param width
     * @param height
     * @param editType = c 取中心化缩略图,否则取原等比缩略图
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void thumbnailImg(String inImgPath,String outImgPath,Integer width,Integer height,String editType) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //取中心化或者原图同比
        if(editType!=null && editType.equals("c")) {
            //分析宽高 先原图等比生成缩略图(缩略规则按原图大的一边为准取值)
            Info info = new Info(inImgPath);
            Integer init_width = info.getImageWidth();
            Integer init_height = info.getImageHeight();
            double width_v = (double)init_width/width;
            double height_v = (double)init_height/height;
            //原图是正方形
            /*if(init_width == init_height){
                operation.thumbnail(width,height);
                //原图是宽大于高的长方形
            }else */if(init_width >= init_height){
                if (width_v >= height_v) {
                    operation.thumbnail(null,height);
                } else if (width_v < height_v) {
                    operation.thumbnail(width,null);
                }
                //原图是高大于宽的长方形
            }else if(init_width < init_height){if (width_v > height_v) {
                operation.thumbnail(null,height);
            } else if (width_v <= height_v) {
                operation.thumbnail(width,null);
            }
            }
            //再中心化截图
            operation.gravity("center");
            operation.crop(width, height,0,0);
        }else{
            operation.thumbnail(width,height);
        }
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 旋转图片
     * @param inImgPath
     * @param outImgPath
     * @param x 旋转角度
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void rotateImg(String inImgPath,String outImgPath,Double x) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        operation.rotate(x);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 缩略图 (原图画质缩略)
     * @param inImgPath
     * @param outImgPath
     * @param width
     * @param height
     * @param editType
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void sampleImg(String inImgPath,String outImgPath,Integer width,Integer height,String editType) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //取中心化或者原图同比
        if(editType!=null && editType.equals("center")) {
            getCenterSquare(inImgPath,operation);
        }
        operation.sample(width,height);
//        operation.quality(5.0); //设置生成图片质量
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 将图片变成黑白图片
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void monochrome(String inImgPath,String outImgPath) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        operation.monochrome();
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 给图片加水印
     * @param: srcPath源图片路径
     */
    public static void addImgText(String inImgPath,String outImgPath,String str)throws IOException, InterruptedException, IM4JavaException{
        IMOperation operation = new IMOperation();
        operation.font("宋体").gravity("southeast").pointsize(18).fill("#BCBFC8")
            .draw("text 5,5 "+str);
        operation.encoding("UTF-8");
        operation.addImage();
        operation.addImage();
        ConvertCmd convert = new ConvertCmd();
        convert.run(operation, inImgPath,outImgPath);
    }
    /**
     * 创建文件名称
     * @param folder
     * @param fileName
     * @return
     */
    public static File createFile(String folder, String fileName) {
        File serverFile;
        String suffix = getSuffix(fileName);
        String destFileName = null;
        long timeMillis = System.currentTimeMillis();
        int i = 1;
        do {
            if (suffix.length() == 0) {
                destFileName = String.format("%s_%d", timeMillis, i++);
            } else {
                destFileName = String.format("%s_%d.%s", timeMillis, i++, suffix);
            }
            serverFile = new File(folder, destFileName);
        } while (serverFile.exists());
        serverFile.getParentFile().mkdirs();
        return serverFile;
    }
    /**
     * 生成图片名称(根据旧的文件类型)
     * @param rootPath 文件目录地址
     * @param oldFileName 文件相对路径
     * @param type 操作类型 c :中心化、o :原比例、自定义
     * @return
     */
    public  String  createFileName(String rootPath,String oldFileName,int width,int height,String type) {
        // 初始化目录
        String pathName = oldFileName.substring(0,oldFileName.lastIndexOf("/"));
        String newFilePath = rootPath + pathName;
        File dirFile = new File(newFilePath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        // 生成文件名
        String imgName =oldFileName.substring(oldFileName.lastIndexOf("/"));
        String a = imgName.substring(0,imgName.lastIndexOf("."));
        String b = imgName.substring(imgName.lastIndexOf("."));
        return  newFilePath + a + "_"+ width + "x"+ height +"_" + type + b;
    }
    /**
     * 截取文件名称
     * @param filePath
     * @return
     */
    public static String getSuffix(String filePath){
        return filePath.substring(filePath.lastIndexOf("."));
    }
    /**
     * main方法测试
     * @param args
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void main(String[] args) throws IOException, InterruptedException, IM4JavaException{
//        String inImgPath = "D:\\Documents\\Pictures\\1.jpg";
//        String outImgPath = "D:\\Documents\\Pictures\\2.jpg";
        Img4JavaUtil test = new Img4JavaUtil();
        // 中心化缩略图(常用)
//        test.thumbnailImg(inImgPath,outImgPath,400,400,"c");
        // 裁剪图片
//        test.cropImg(inImgPath,outImgPath+"裁剪-300x300.jpg",300,300,0,0);
        // 获取图片信息
//        test.getImgInfo(inImgPath);
        // 等比缩放
//        test.resizeImg(inImgPath,outImgPath+"等比缩放-w300.jpg",300,null);
        // 旋转图片
//        test.rotateImg(inImgPath,outImgPath+"旋转45.jpg",45.0);
        // 转黑白图片
//        test.monochrome(inImgPath,outImgPath+"转黑白.jpg");
        // 加水印
//        test.addImgText(inImgPath,outImgPath+"加水印.jpg","CCTV-100");
        // 原图质量缩放
//        test.scaleImg(inImgPath,outImgPath+"缩略图scale.jpg",100,null);
        // 自动中心化裁剪
//        test.cropCenterImg(inImgPath,outImgPath+"中心.jpg",400,300);
    }
}
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/OSinfo.java
New file
@@ -0,0 +1,161 @@
package cn.gistack.resource.panoramaUtils;
/**
 * 操作系统类: 获取System.getProperty("os.name")对应的操作系统
 *
 * @author kelu
 */
public class OSinfo {
    private static String OS = System.getProperty("os.name").toLowerCase();
    private static OSinfo _instance = new OSinfo();
    private EPlatform platform;
    private OSinfo() {
    }
    public static boolean isLinux() {
        return OS.indexOf("linux") >= 0;
    }
    public static boolean isMacOS() {
        return OS.indexOf("mac") >= 0 && OS.indexOf("os") > 0 && OS.indexOf("x") < 0;
    }
    public static boolean isMacOSX() {
        return OS.indexOf("mac") >= 0 && OS.indexOf("os") > 0 && OS.indexOf("x") > 0;
    }
    public static boolean isWindows() {
        return OS.indexOf("windows") >= 0;
    }
    public static boolean isOS2() {
        return OS.indexOf("os/2") >= 0;
    }
    public static boolean isSolaris() {
        return OS.indexOf("solaris") >= 0;
    }
    public static boolean isSunOS() {
        return OS.indexOf("sunos") >= 0;
    }
    public static boolean isMPEiX() {
        return OS.indexOf("mpe/ix") >= 0;
    }
    public static boolean isHPUX() {
        return OS.indexOf("hp-ux") >= 0;
    }
    public static boolean isAix() {
        return OS.indexOf("aix") >= 0;
    }
    public static boolean isOS390() {
        return OS.indexOf("os/390") >= 0;
    }
    public static boolean isFreeBSD() {
        return OS.indexOf("freebsd") >= 0;
    }
    public static boolean isIrix() {
        return OS.indexOf("irix") >= 0;
    }
    public static boolean isDigitalUnix() {
        return OS.indexOf("digital") >= 0 && OS.indexOf("unix") > 0;
    }
    public static boolean isNetWare() {
        return OS.indexOf("netware") >= 0;
    }
    public static boolean isOSF1() {
        return OS.indexOf("osf1") >= 0;
    }
    public static boolean isOpenVMS() {
        return OS.indexOf("openvms") >= 0;
    }
    /**
     * 获取操作系统名字
     *
     * @return 操作系统名
     */
    public static EPlatform getOSname() {
        if (isAix()) {
            _instance.platform = EPlatform.AIX;
        } else if (isDigitalUnix()) {
            _instance.platform = EPlatform.Digital_Unix;
        } else if (isFreeBSD()) {
            _instance.platform = EPlatform.FreeBSD;
        } else if (isHPUX()) {
            _instance.platform = EPlatform.HP_UX;
        } else if (isIrix()) {
            _instance.platform = EPlatform.Irix;
        } else if (isLinux()) {
            _instance.platform = EPlatform.Linux;
        } else if (isMacOS()) {
            _instance.platform = EPlatform.Mac_OS;
        } else if (isMacOSX()) {
            _instance.platform = EPlatform.Mac_OS_X;
        } else if (isMPEiX()) {
            _instance.platform = EPlatform.MPEiX;
        } else if (isNetWare()) {
            _instance.platform = EPlatform.NetWare_411;
        } else if (isOpenVMS()) {
            _instance.platform = EPlatform.OpenVMS;
        } else if (isOS2()) {
            _instance.platform = EPlatform.OS2;
        } else if (isOS390()) {
            _instance.platform = EPlatform.OS390;
        } else if (isOSF1()) {
            _instance.platform = EPlatform.OSF1;
        } else if (isSolaris()) {
            _instance.platform = EPlatform.Solaris;
        } else if (isSunOS()) {
            _instance.platform = EPlatform.SunOS;
        } else if (isWindows()) {
            _instance.platform = EPlatform.Windows;
        } else {
            _instance.platform = EPlatform.Others;
        }
        return _instance.platform;
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(OSinfo.getOSname());
    }
    /**
     * 平台
     *
     * @author isea533
     */
    public enum EPlatform {
        Any("any"), Linux("Linux"), Mac_OS("Mac OS"), Mac_OS_X("Mac OS X"), Windows("Windows"), OS2("OS/2"), Solaris(
            "Solaris"), SunOS("SunOS"), MPEiX("MPE/iX"), HP_UX("HP-UX"), AIX("AIX"), OS390("OS/390"), FreeBSD(
            "FreeBSD"), Irix("Irix"), Digital_Unix("Digital Unix"), NetWare_411(
            "NetWare"), OSF1("OSF1"), OpenVMS("OpenVMS"), Others("Others");
        private EPlatform(String desc) {
            this.description = desc;
        }
        public String toString() {
            return description;
        }
        private String description;
    }
}
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/panoramaUtils/QietuResult.java
New file
@@ -0,0 +1,49 @@
package cn.gistack.resource.panoramaUtils;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
 * @author kelu
 */
@Data
public class QietuResult {
    /**
     * 图片路径
     */
    private List<String>  qieTuUrlList;
    /**
     * 图片路径头
     */
    private String  urlHead;
    /**
     * 原始全景图片名称
     */
    private String  qjName;
    /**
     * 原始全景图片上传路径
     */
    private String  qjUrl;
    /**
     * 原始全景图片长
     */
    private Integer  quanJingHeight;
    /**
     * 原始全景图片宽
     */
    private Integer  quanJingWidth;
    /**
     * 原始全景图片,切图的列数
     */
    private Integer  col;
    /**
     * 原始全景图片,切图的行数
     */
    private Integer  row;
}
skjcmanager/skjcmanager-ops/skjcmanager-resource/src/main/java/cn/gistack/resource/rule/PanoramaOSSRule.java
New file
@@ -0,0 +1,50 @@
package cn.gistack.resource.rule;
import com.alibaba.cloud.commons.lang.StringUtils;
import org.springblade.core.oss.rule.BladeOssRule;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.FileUtil;
/**
 * PanoramaOSSRule
 *
 * @author kelu
 */
public class PanoramaOSSRule extends BladeOssRule {
    private String prefixPath;
    private String resGuid;
    @Override
    public String bucketName(String bucketName) {
        return super.bucketName(bucketName);
    }
    public PanoramaOSSRule(Boolean tenantMode) {
        super(tenantMode);
    }
    public PanoramaOSSRule(Boolean tenantMode, String prefixPath) {
        super(tenantMode);
        this.prefixPath = prefixPath;
    }
    public PanoramaOSSRule(Boolean tenantMode, String prefixPath , String resGuid) {
        super(tenantMode);
        this.prefixPath = prefixPath;
        this.resGuid = resGuid;
    }
    @Override
    public String fileName(String originalFilename) {
        String resGuidUrl = "";
        if(StringUtils.isNotBlank(this.resGuid)) {
            resGuidUrl = "/" + this.resGuid ;
        }
        String  lastUrl = this.prefixPath+ resGuidUrl + "/" + DateUtil.today() + "/" +  originalFilename;
        return lastUrl;
    }
}
skjcmanager/skjcmanager-service/skjcmanager-sm/pom.xml
@@ -76,6 +76,11 @@
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-resource-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-starter-excel</artifactId>
        </dependency>
@@ -103,6 +108,12 @@
            <artifactId>poi-tl</artifactId>
            <version>1.8.2</version>
        </dependency>
        <!-- ImageMagick切图 -->
        <dependency>
            <groupId>org.im4java</groupId>
            <artifactId>im4java</artifactId>
            <version>1.4.0</version>
        </dependency>
    </dependencies>
    <build>
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/controller/SkPanoramaController.java
@@ -16,8 +16,14 @@
 */
package cn.gistack.sm.skPanorama.controller;
import cn.gistack.resource.entity.QieTuEntity;
import cn.gistack.resource.feign.IOssClient;
import cn.gistack.sm.skPanorama.utils.Img4JavaUtil;
import cn.gistack.sm.skPanoramaState.entity.SkPanoramaStateEntity;
import cn.gistack.sm.skPanoramaState.service.ISkPanoramaStateService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -26,11 +32,16 @@
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.im4java.core.IM4JavaException;
import org.im4java.core.InfoException;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import cn.gistack.sm.skPanorama.entity.SkPanoramaEntity;
@@ -39,8 +50,13 @@
import cn.gistack.sm.skPanorama.service.ISkPanoramaService;
import org.springblade.core.boot.ctrl.BladeController;
import java.util.ArrayList;
import java.util.List;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
/**
 * 水库全景图 控制器
@@ -56,13 +72,18 @@
@Slf4j
@Api(tags="全景")
@RestController
    @RequestMapping("/skPanorama")
@RequestMapping("/skPanorama")
@AllArgsConstructor
public class SkPanoramaController extends BladeController {
    private final ISkPanoramaService skPanoramaService;
    private final ISkPanoramaStateService skPanoramaStateService;
    /**
     * 对象存储构建类
     */
    private final IOssClient iOssClient;
    /**
     * 水库全景图 详情
@@ -179,4 +200,162 @@
        return R.data(list);
    }
    /**
     * 全景图切图
     * 等比例切图
     * 长col:8
     * 宽row:4
    @GetMapping("/cutPicture")
    public void cutPicture(SkPanoramaEntity skPanorama) throws  IOException {
        // 临时文件路径
        String  linShiBaseUrl = "/data/panorama/qietu/";
        int col = 8;
        int row = 4;
        SkPanoramaEntity entity = skPanoramaService.getOne(Condition.getQueryWrapper(skPanorama));
        String picUrl = entity.getPicUrl();
        String picName = entity.getPicName();
        String resGuid = entity.getResGuid();
        String[] split = picName.split("\\.");
        String picHeadName = split[0];
        String picLastName = split[1];
        HashMap<String, Integer> imgInfoRT = Img4JavaUtil.getImgInfoRT(picUrl);
        Integer width = imgInfoRT.get("width");
        Integer height = imgInfoRT.get("height");
        // 计算切成小图的长和宽
        Integer biliWidth = width/col;
        Integer biliHeight = height/row;
        for (int i=0 ; i < col ; i++) {
            // 计算图片的横坐标(长边)
            int x = i * biliWidth;
            for (int j=0 ; j<row ; j++){
                // 计算图片的纵坐标(宽边)
                int  y = j * biliHeight;
                // 图片名
                String outpicName = picHeadName + "_" + i + "_" +j + "." + picLastName;
//                Img4JavaUtil.cropImg(picUrl,"C:/Users/kelu/Desktop/qietuTest/"+outpicName,biliWidth,biliHeight,x,y);
            }
        }
    }
     */
    @GetMapping("/cutPicture2")
    public R cutPicture2(SkPanoramaEntity skPanorama)
        throws IOException, InterruptedException, IM4JavaException, IllegalAccessException {
        // 临时文件路径
        String  linShiBaseUrl = "/data/panorama/qietu/";
        SkPanoramaEntity entity = skPanoramaService.getOne(Condition.getQueryWrapper(skPanorama));
        String picUrl = entity.getPicUrl();
        String picName = entity.getPicName();
        String resGuid = entity.getResGuid();
        // 获取文件名
        String dirPath = linShiBaseUrl + resGuid + "/"; //临时文件夹路径
        String lingshiPic = linShiBaseUrl + resGuid + "/" + picName; //临时文件
        File dir = new File(dirPath);
        if (dir.isDirectory()) {
            // 清除该目录下的文件及子目录文件而不删除该目录文件夹。该目录不存在会报错
            FileUtils.cleanDirectory(dir);
        } else {
            dir.mkdirs();
        }
        // 线上全景图路径,下载到临时路径
        URL url = new URL(picUrl);
        InputStream inputStream = url.openStream();
        OutputStream outputStream = new FileOutputStream(lingshiPic);
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        inputStream.close();
        outputStream.close();
        Path lingshiqjPath = Paths.get(lingshiPic);
        File lingshiqjfile = lingshiqjPath.toFile(); // 获取临时全景文件,准备切图
        /**
         * 这里开始切图
         */
        HashMap<String,String> qietuHashMap = new HashMap<String,String>();
        int col = 4;
        int row = 4;
        String[] split = picName.split("\\.");
        String picHeadName = split[0];
        String picLastName = split[1];
        // 获取原始全景图图片信息
        HashMap<String, Integer> imgInfoRT = Img4JavaUtil.getImgInfoRT(lingshiqjfile);
        Integer width = imgInfoRT.get("width");
        Integer height = imgInfoRT.get("height");
        // 计算切成小图的长和宽
        Integer biliWidth = width/col;
        Integer biliHeight = height/row;
        for (int i=0 ; i < col ; i++) {
            // 计算图片的横坐标(长边)
            int x = i * biliWidth;
            for (int j=0 ; j<row ; j++){
                // 计算图片的纵坐标(宽边)
                int  y = j * biliHeight;
                // 切图名称
                String outpicName = picHeadName + "_" + i + "_" +j + "." + picLastName;
                // 切图后临时图片的的路径
                String lastiUrl = dirPath + outpicName;
                Img4JavaUtil.cropImg(picUrl ,lastiUrl ,biliWidth,biliHeight,x,y);// 切图存放进临时图片中
                qietuHashMap.put(outpicName,lastiUrl);
                System.err.println(lastiUrl);
            }
        }
        // 切图完成后删除原始全景图
        if (lingshiqjfile.exists()) {
            // 删除指定文件,不存在报异常
            FileUtils.forceDelete(lingshiqjfile);
        }
        /************************************切图结束********************************************/
        // 上传切片全景图
        System.err.println(qietuHashMap.size());
        System.err.println(resGuid);
        QieTuEntity qieTuEntity = new QieTuEntity();
        qieTuEntity.setQietuHashMap(qietuHashMap);
        qieTuEntity.setResGuid(resGuid);
        R r = iOssClient.uploadQietu(qieTuEntity);
        Object data = r.getData();
        QieTuEntity result = JSONObject.parseObject(JSONObject.toJSONString(data),QieTuEntity.class);
        HashMap<String, String> resultMap = result.getQietuHashMap();
        String qturlList = resultMap.get("qturlList");
        String urlHead = resultMap.get("urlHead");
        entity.setQietuurllist(qturlList);
        entity.setUrlhead(urlHead);
        entity.setQierow(row);
        entity.setQiecol(col);
        entity.setPicwidth(width);
        entity.setPicheight(height);
        skPanoramaService.updateById(entity);
        return R.status(true);
    }
}
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/entity/SkPanoramaEntity.java
@@ -107,4 +107,31 @@
     */
    @ApiModelProperty(value = "全景图模型的默认方向")
    private Double pitch;
    /**
     * 切图图片路径
     */
    private String  qietuurllist;
    /**
     * 切图图片路径头
     */
    private String  urlhead;
    /**
     * 原始全景图片宽
     */
    private Integer  picheight;
    /**
     * 原始全景图片长
     */
    private Integer  picwidth;
    /**
     * 原始全景图片,切图的列数
     */
    private Integer  qiecol;
    /**
     * 原始全景图片,切图的行数
     */
    private Integer  qierow;
}
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/mapper/SkPanoramaMapper.xml
@@ -24,7 +24,12 @@
    <select id="selectSkPanoramaPage" resultMap="skPanoramaResultMap">
        select * from sk_panorama where is_deleted = 0
        select
            *
        from
            sk_panorama
        where
            is_deleted = 0
    </select>
    <resultMap id="skResultMap" type="cn.gistack.sm.skPanorama.entity.SkPanoramaEntity">
@@ -34,12 +39,20 @@
        <result column="sort" property="sort"/>
        <result column="name" property="name"/>
        <result column="pic_url" property="picUrl"/>
        <result column="pic_name" property="picName"/>
        <result column="small_pic_url" property="smallPicUrl"/>
        <result column="shooting_time" property="shootingTime"/>
        <result column="shooting_angle" property="shootingAngle"/>
        <result column="shooting_dept" property="shootingDept"/>
        <result column="mryaw" property="yaw"/>
        <result column="mrpitch" property="pitch"/>
        <result column="qietuurllist" property="qietuurllist"/>
        <result column="urlhead" property="urlhead"/>
        <result column="picheight" property="picheight"/>
        <result column="picwidth" property="picwidth"/>
        <result column="qiecol" property="qiecol"/>
        <result column="qierow" property="qierow"/>
        <collection property="stateLsit" ofType="cn.gistack.sm.skPanoramaState.entity.SkPanoramaStateEntity">
            <result column="sps_id" property="id"/>
            <result column="sk_panorama_id" property="skPanoramaId"/>
@@ -62,12 +75,19 @@
            SP.sort ,
            SP.name ,
            SP.pic_url ,
            SP.pic_name ,
            SP.small_pic_url ,
            SP.shooting_time ,
            SP.shooting_angle ,
            SP.shooting_dept ,
            SP.yaw AS "mryaw",
            SP.pitch AS "mrpitch",
            SP.qietuurllist AS "qietuurllist",
            SP.urlhead AS "urlhead",
            SP.picheight AS "picheight",
            SP.picwidth AS "picwidth",
            SP.qiecol AS "qiecol",
            SP.qierow AS "qierow",
            SPS.id AS "sps_id",
            SPS.sk_panorama_id ,
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/utils/Img4JavaUtil.java
New file
@@ -0,0 +1,438 @@
package cn.gistack.sm.skPanorama.utils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IM4JavaException;
import org.im4java.core.IMOperation;
import org.im4java.core.Info;
import org.im4java.core.InfoException;
import org.im4java.process.ProcessStarter;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.ClassUtils;
import org.springframework.util.ResourceUtils;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import static java.awt.SystemColor.info;
public class Img4JavaUtil {
    static {
        //判断是否是windows系统
        if(OSinfo.isWindows()) {
            System.out.println("------------ START 初始化ImageMagickPath -------------");
            ProcessStarter.setGlobalSearchPath("D:/im4java/ImageMagick-7.1.1-Q16-HDRI");
            System.out.println("------------ END 初始化ImageMagickPath -------------");
        } else if (OSinfo.isLinux()) {
            System.out.println("------------ START 初始化ImageMagickPath -------------");
//            ProcessStarter.setGlobalSearchPath("D:/im4java/ImageMagick-7.1.1-Q16-HDRI");
            System.out.println("------------ END 初始化ImageMagickPath -------------");
        }
    }
    /**
     * 裁剪图片
     * @param inImgPath 源图片地址
     * @param outImgPath 目标图片地址
     * @param width 宽
     * @param height 高
     * @param x 起点横坐标
     * @param y 起点纵坐标
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void cropImg(String inImgPath,String outImgPath,Integer width,Integer height,Integer x,Integer y)
        throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //宽  高 起点横坐标 起点纵坐标
        operation.crop(width, height, x, y);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 裁剪图片
     * @param inImgPath 源图片地址
     * @param outImgPath 目标图片地址
     * @param width 宽
     * @param height 高
     * @param x 起点横坐标
     * @param y 起点纵坐标
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
//    public void cropImg(String inImgPath,String outImgPath,Integer width,Integer height,Integer x,Integer y)
//        throws IOException, InterruptedException, IM4JavaException{
//        ConvertCmd cmd = new ConvertCmd();
//        IMOperation operation = new IMOperation();
//        operation.addImage(inImgPath);
//        //宽  高 起点横坐标 起点纵坐标
//        operation.crop(width, height, x, y);
//        operation.addImage(outImgPath);
//        cmd.run(operation);
//    }
    /**
     * 裁剪中心化图片
     * @param inImgPath 源图片地址
     * @param outImgPath 目标图片地址
     * @param width 宽
     * @param height 高
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void cropCenterImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        Info info = new Info(inImgPath);
        Integer init_width = info.getImageWidth();
        Integer init_height = info.getImageHeight();
        // 如果裁剪的宽高都大于原始图片宽高 则先等比放大再裁剪
        if(width>init_width || height>init_height){
            // 等比放大
            Integer temp_width = width;
            if(init_height<init_width){
                // 如果原图宽大于高 则以高为准放大
                temp_width = null;
            }
            operation.resize(temp_width, height);
        }
        operation.addImage(inImgPath);
        //宽  高 起点横坐标 起点纵坐标
        operation.gravity("center");
        operation.crop(width, height, 0, 0);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 得到图片的信息
     * @throws InfoException
     */
    public static String getImgInfo(String inImgPath) throws InfoException{
        Info info = new Info(inImgPath);
//        System.out.println(info.getImageHeight());
//        System.out.println(info.getImageWidth());
        return info.getImageWidth()+"x"+info.getImageHeight();
    }
    /**
     * 得到图片的信息
     * @throws InfoException
     */
    public static HashMap<String,Integer> getImgInfoRT( File imageFile) throws  IOException {
        HashMap stringHashMap = new HashMap<String,Integer>();
        try {
            ImageInputStream imageInputStream = ImageIO.createImageInputStream(imageFile);
            final Iterator<ImageReader> readers = ImageIO.getImageReaders(imageInputStream);
            if(readers.hasNext()){
                ImageReader reader = readers.next();
                reader.setInput(imageInputStream,true);
                int width = reader.getWidth(0);
                int height = reader.getHeight(0);
                stringHashMap.put("width",width);
                stringHashMap.put("height",height);
                imageInputStream.close();
            }
        } catch (IOException e) {
            System.err.println("IOException "+e.getMessage());
        }
        return stringHashMap;
    }
    /**
     * 等比缩放图片
     * @param inImgPath
     * @param outImgPath
     * @param width 宽度不为空时 以宽度为准,为空时以高度为准(不能同时为空)
     * @param height
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void resizeImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //等比缩放图片
        operation.resize(width, height);//高度为null则按宽度缩放
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 等比缩放   (使用像素平均缩小)
     * @param inImgPath
     * @param outImgPath
     * @param width
     * @param height
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void scaleImg(String inImgPath,String outImgPath,Integer width,Integer height) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //缩略图
        operation.scale(width,height);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 把原图裁剪成正方形
     * @param inImgPath
     * @param operation
     * @return
     * @throws IM4JavaException
     */
    public static IMOperation getCenterSquare(String inImgPath,IMOperation operation)throws IM4JavaException{
        Info info = new Info(inImgPath);
        Integer init_width = info.getImageWidth();
        Integer init_height = info.getImageHeight();
        if (init_width > init_height) {
            init_width = init_height;
        } else if (init_width < init_height) {
            init_height = init_width;
        }
        operation.gravity("center");
        operation.crop(init_width, init_height,0,0);
        return operation;
    }
    /**
     * 缩略图 (专门用于将非常大的图像缩小为小缩略图)
     * @param inImgPath
     * @param outImgPath
     * @param width
     * @param height
     * @param editType = c 取中心化缩略图,否则取原等比缩略图
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void thumbnailImg(String inImgPath,String outImgPath,Integer width,Integer height,String editType) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //取中心化或者原图同比
        if(editType!=null && editType.equals("c")) {
            //分析宽高 先原图等比生成缩略图(缩略规则按原图大的一边为准取值)
            Info info = new Info(inImgPath);
            Integer init_width = info.getImageWidth();
            Integer init_height = info.getImageHeight();
            double width_v = (double)init_width/width;
            double height_v = (double)init_height/height;
            //原图是正方形
            /*if(init_width == init_height){
                operation.thumbnail(width,height);
                //原图是宽大于高的长方形
            }else */if(init_width >= init_height){
                if (width_v >= height_v) {
                    operation.thumbnail(null,height);
                } else if (width_v < height_v) {
                    operation.thumbnail(width,null);
                }
                //原图是高大于宽的长方形
            }else if(init_width < init_height){if (width_v > height_v) {
                operation.thumbnail(null,height);
            } else if (width_v <= height_v) {
                operation.thumbnail(width,null);
            }
            }
            //再中心化截图
            operation.gravity("center");
            operation.crop(width, height,0,0);
        }else{
            operation.thumbnail(width,height);
        }
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 旋转图片
     * @param inImgPath
     * @param outImgPath
     * @param x 旋转角度
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void rotateImg(String inImgPath,String outImgPath,Double x) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        operation.rotate(x);
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 缩略图 (原图画质缩略)
     * @param inImgPath
     * @param outImgPath
     * @param width
     * @param height
     * @param editType
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void sampleImg(String inImgPath,String outImgPath,Integer width,Integer height,String editType) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        //取中心化或者原图同比
        if(editType!=null && editType.equals("center")) {
            getCenterSquare(inImgPath,operation);
        }
        operation.sample(width,height);
//        operation.quality(5.0); //设置生成图片质量
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 将图片变成黑白图片
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public void monochrome(String inImgPath,String outImgPath) throws IOException, InterruptedException, IM4JavaException{
        ConvertCmd cmd = new ConvertCmd();
        IMOperation operation = new IMOperation();
        operation.addImage(inImgPath);
        operation.monochrome();
        operation.addImage(outImgPath);
        cmd.run(operation);
    }
    /**
     * 给图片加水印
     * @param: srcPath源图片路径
     */
    public static void addImgText(String inImgPath,String outImgPath,String str)throws IOException, InterruptedException, IM4JavaException{
        IMOperation operation = new IMOperation();
        operation.font("宋体").gravity("southeast").pointsize(18).fill("#BCBFC8")
            .draw("text 5,5 "+str);
        operation.encoding("UTF-8");
        operation.addImage();
        operation.addImage();
        ConvertCmd convert = new ConvertCmd();
        convert.run(operation, inImgPath,outImgPath);
    }
    /**
     * 创建文件名称
     * @param folder
     * @param fileName
     * @return
     */
    public static File createFile(String folder, String fileName) {
        File serverFile;
        String suffix = getSuffix(fileName);
        String destFileName = null;
        long timeMillis = System.currentTimeMillis();
        int i = 1;
        do {
            if (suffix.length() == 0) {
                destFileName = String.format("%s_%d", timeMillis, i++);
            } else {
                destFileName = String.format("%s_%d.%s", timeMillis, i++, suffix);
            }
            serverFile = new File(folder, destFileName);
        } while (serverFile.exists());
        serverFile.getParentFile().mkdirs();
        return serverFile;
    }
    /**
     * 生成图片名称(根据旧的文件类型)
     * @param rootPath 文件目录地址
     * @param oldFileName 文件相对路径
     * @param type 操作类型 c :中心化、o :原比例、自定义
     * @return
     */
    public  String  createFileName(String rootPath,String oldFileName,int width,int height,String type) {
        // 初始化目录
        String pathName = oldFileName.substring(0,oldFileName.lastIndexOf("/"));
        String newFilePath = rootPath + pathName;
        File dirFile = new File(newFilePath);
        if (!dirFile.exists()) {
            dirFile.mkdirs();
        }
        // 生成文件名
        String imgName =oldFileName.substring(oldFileName.lastIndexOf("/"));
        String a = imgName.substring(0,imgName.lastIndexOf("."));
        String b = imgName.substring(imgName.lastIndexOf("."));
        return  newFilePath + a + "_"+ width + "x"+ height +"_" + type + b;
    }
    /**
     * 截取文件名称
     * @param filePath
     * @return
     */
    public static String getSuffix(String filePath){
        return filePath.substring(filePath.lastIndexOf("."));
    }
    /**
     * main方法测试
     * @param args
     * @throws IOException
     * @throws InterruptedException
     * @throws IM4JavaException
     */
    public static void main(String[] args) throws IOException, InterruptedException, IM4JavaException{
        String inImgPath = "D:\\Documents\\Pictures\\1.jpg";
        String outImgPath = "D:\\Documents\\Pictures\\2.jpg";
        Img4JavaUtil test = new Img4JavaUtil();
        // 中心化缩略图(常用)
        test.thumbnailImg(inImgPath,outImgPath,400,400,"c");
        // 裁剪图片
//        test.cropImg(inImgPath,outImgPath+"裁剪-300x300.jpg",300,300,0,0);
        // 获取图片信息
//        test.getImgInfo(inImgPath);
        // 等比缩放
//        test.resizeImg(inImgPath,outImgPath+"等比缩放-w300.jpg",300,null);
        // 旋转图片
//        test.rotateImg(inImgPath,outImgPath+"旋转45.jpg",45.0);
        // 转黑白图片
//        test.monochrome(inImgPath,outImgPath+"转黑白.jpg");
        // 加水印
//        test.addImgText(inImgPath,outImgPath+"加水印.jpg","CCTV-100");
        // 原图质量缩放
//        test.scaleImg(inImgPath,outImgPath+"缩略图scale.jpg",100,null);
        // 自动中心化裁剪
//        test.cropCenterImg(inImgPath,outImgPath+"中心.jpg",400,300);
    }
}
skjcmanager/skjcmanager-service/skjcmanager-sm/src/main/java/cn/gistack/sm/skPanorama/utils/OSinfo.java
New file
@@ -0,0 +1,161 @@
package cn.gistack.sm.skPanorama.utils;
/**
 * 操作系统类: 获取System.getProperty("os.name")对应的操作系统
 *
 * @author isea533
 */
public class OSinfo {
    private static String OS = System.getProperty("os.name").toLowerCase();
    private static OSinfo _instance = new OSinfo();
    private EPlatform platform;
    private OSinfo() {
    }
    public static boolean isLinux() {
        return OS.indexOf("linux") >= 0;
    }
    public static boolean isMacOS() {
        return OS.indexOf("mac") >= 0 && OS.indexOf("os") > 0 && OS.indexOf("x") < 0;
    }
    public static boolean isMacOSX() {
        return OS.indexOf("mac") >= 0 && OS.indexOf("os") > 0 && OS.indexOf("x") > 0;
    }
    public static boolean isWindows() {
        return OS.indexOf("windows") >= 0;
    }
    public static boolean isOS2() {
        return OS.indexOf("os/2") >= 0;
    }
    public static boolean isSolaris() {
        return OS.indexOf("solaris") >= 0;
    }
    public static boolean isSunOS() {
        return OS.indexOf("sunos") >= 0;
    }
    public static boolean isMPEiX() {
        return OS.indexOf("mpe/ix") >= 0;
    }
    public static boolean isHPUX() {
        return OS.indexOf("hp-ux") >= 0;
    }
    public static boolean isAix() {
        return OS.indexOf("aix") >= 0;
    }
    public static boolean isOS390() {
        return OS.indexOf("os/390") >= 0;
    }
    public static boolean isFreeBSD() {
        return OS.indexOf("freebsd") >= 0;
    }
    public static boolean isIrix() {
        return OS.indexOf("irix") >= 0;
    }
    public static boolean isDigitalUnix() {
        return OS.indexOf("digital") >= 0 && OS.indexOf("unix") > 0;
    }
    public static boolean isNetWare() {
        return OS.indexOf("netware") >= 0;
    }
    public static boolean isOSF1() {
        return OS.indexOf("osf1") >= 0;
    }
    public static boolean isOpenVMS() {
        return OS.indexOf("openvms") >= 0;
    }
    /**
     * 获取操作系统名字
     *
     * @return 操作系统名
     */
    public static EPlatform getOSname() {
        if (isAix()) {
            _instance.platform = EPlatform.AIX;
        } else if (isDigitalUnix()) {
            _instance.platform = EPlatform.Digital_Unix;
        } else if (isFreeBSD()) {
            _instance.platform = EPlatform.FreeBSD;
        } else if (isHPUX()) {
            _instance.platform = EPlatform.HP_UX;
        } else if (isIrix()) {
            _instance.platform = EPlatform.Irix;
        } else if (isLinux()) {
            _instance.platform = EPlatform.Linux;
        } else if (isMacOS()) {
            _instance.platform = EPlatform.Mac_OS;
        } else if (isMacOSX()) {
            _instance.platform = EPlatform.Mac_OS_X;
        } else if (isMPEiX()) {
            _instance.platform = EPlatform.MPEiX;
        } else if (isNetWare()) {
            _instance.platform = EPlatform.NetWare_411;
        } else if (isOpenVMS()) {
            _instance.platform = EPlatform.OpenVMS;
        } else if (isOS2()) {
            _instance.platform = EPlatform.OS2;
        } else if (isOS390()) {
            _instance.platform = EPlatform.OS390;
        } else if (isOSF1()) {
            _instance.platform = EPlatform.OSF1;
        } else if (isSolaris()) {
            _instance.platform = EPlatform.Solaris;
        } else if (isSunOS()) {
            _instance.platform = EPlatform.SunOS;
        } else if (isWindows()) {
            _instance.platform = EPlatform.Windows;
        } else {
            _instance.platform = EPlatform.Others;
        }
        return _instance.platform;
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(OSinfo.getOSname());
    }
    /**
     * 平台
     *
     * @author isea533
     */
    public enum EPlatform {
        Any("any"), Linux("Linux"), Mac_OS("Mac OS"), Mac_OS_X("Mac OS X"), Windows("Windows"), OS2("OS/2"), Solaris(
            "Solaris"), SunOS("SunOS"), MPEiX("MPE/iX"), HP_UX("HP-UX"), AIX("AIX"), OS390("OS/390"), FreeBSD(
            "FreeBSD"), Irix("Irix"), Digital_Unix("Digital Unix"), NetWare_411(
            "NetWare"), OSF1("OSF1"), OpenVMS("OpenVMS"), Others("Others");
        private EPlatform(String desc) {
            this.description = desc;
        }
        public String toString() {
            return description;
        }
        private String description;
    }
}