OpenSlide-Java与Springboot集成(minio存储)

OpenSlide-Java与Springboot集成(minio存储)

前言:关于OpenSlide与java集成的例子比较少,在网上找了半天资料也没多少有用的。只能靠着少数资料去摸索和尝试,终于可以用上了,主要是用java操作openSlide去切割大图文件,希望下面的方式能帮到你们。

一、OpenSlide环境安装(windows版本)

1、下载二进制文件:https://openslide.org/download/

在这里插入图片描述

根据自己的系统去下载。

2、将下载好的文件解压到某个目录

在这里插入图片描述

3、配置好环境变量

高级系统设置-》环境变量-》path中添加

在这里插入图片描述

这样openslide就算配置好了。

二、OpenSlide-Java jar包的引入

1、根据git地址的源码拉取代码到本地打包:https://github.com/openslide/openslide-java

在IDEA中下载ant插件,在右边ant模块中直接点击 jar 打包,打包完毕后,项目最下方会出现openslide.jar文件。

在这里插入图片描述

2、将打好的jar包引入本地仓库(也可以在项目中导入包进去,这里使用的maven引入方式)

mvn install:install-file -DgroupId=org.openslide -DartifactId=openslide -Dversion=3.4.1  -Dpackaging=jar -Dfile=D:\java\current-jar\openslide.jar

三、在springboot中集成openSlide-java

1、在pom文件中添加本地仓库依赖

<dependency>
    <groupId>org.openslide</groupId>
    <artifactId>openslide</artifactId>
    <version>3.4.1</version>
</dependency>
    
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <scope>compile</scope>
</dependency>

2、加上yml配置文件

# openSlide相关配置
open-slide:
  img-size: 256 # 切割的图片像素
  img-type: jpg # 切割的图片类型

3、编写工具类(添加依赖后已经引入),直接贴代码了

里面关于minio的工具类


/**
 * @author: chong
 * @E-mail: 1207239331@qq.com
 * @create: 2022-04-19 11:05
 * @desc:
 */
@Slf4j
@Component
public class OpenSlideUtil {

    @Value("${open-slide.img-type}")
    private String imgType;

    @Value("${open-slide.img-size}")
    private Integer imgSize;

    @Resource
    private MinIoUtils minIoUtils;

    private static boolean OPENSLIDE_UNAVAILABLE = false;

    private static final String osName = System.getProperty("os.name");

    private static final List<String> WIN_LIBRARIES = Arrays.asList(
            "iconv",
            "libjpeg-62",
            "libsqlite3-0",
            "libpixman-1-0",
            "libffi-6",
            "zlib1",
            "libxml2-2",
            "libopenjp2",
            "libpng16-16",
            "libtiff-5",
            "libintl-8",
            "libglib-2.0-0",
            "libgobject-2.0-0",
            "libcairo-2",
            "libgmodule-2.0-0",
            "libgio-2.0-0",
            "libgthread-2.0-0",
            "libgdk_pixbuf-2.0-0",
            "libopenslide-0"
    );

    static {
        try {
            // Try loading OpenSlide-JNI - hopefully there is a version of OpenSlide on the PATH we should use
            // 确保本系统已经安装了对应版本的openslide文件并设置了环境变量
            if (osName.startsWith("Windows")) {
                log.info("已检测到您当前使用的系统为:WIN");
                System.loadLibrary("openslide-jni");
                log.info("openslide-jni load success");
            } else if (osName.startsWith("Linux")) {
                // linux的so包可以去相关网站下载或者按官网操作打包,目前作者还未用到
                log.info("已检测到您当前使用的系统为:Linux");
                System.loadLibrary("libopenslide-jni");
                log.info("libopenslide-jni load success");
            }
        } catch (UnsatisfiedLinkError e) {
            try {
                // If we didn't succeed, try loading dependencies in reverse order
                log.error("Couldn't load OpenSlide directly, attempting to load dependencies first...");
                if (osName.startsWith("Windows")) {
                    for (String lib : WIN_LIBRARIES) {
                        System.loadLibrary(lib);
                    }
                }
            } catch (UnsatisfiedLinkError ignored) {
            }
        }
        try {
            // Finally try to get the library version
            log.info("OpenSlide version {}", OpenSlide.getLibraryVersion());
        } catch (UnsatisfiedLinkError e) {
            log.error("Could not load OpenSlide native libraries", e);
            log.info("If you want to use OpenSlide, you'll need to get the native libraries (either building from source or with a packager manager)\n" +
                    "and add them to your system PATH, including openslide-jni.");
            OPENSLIDE_UNAVAILABLE = true;
        }
    }

    /**
     * cutImg
     * 切割图片文件
     * 这个用作本地测试
     * @author: chong
     * @param: infile 输入的文件
     * @param: outfile 输出的文件目录
     * @return: String 文件输出地址
     * @description: 获取文件中的附带文件
     * @date: 2022/4/19
     */
    public List<String> cutImg(File infile, File outfile) {
        // 自定义异常,可以根据自己的需要判断或者删除(相关类不进行粘贴)
        SysException.throwException(OPENSLIDE_UNAVAILABLE, ResultCodeEnum.FAIL.code(), "OpenSlide is unavailable - will be skipped");
        List<String> resultAddress = Lists.newArrayList();
        String fileName = infile.getName();
        String nameWithoutExtension = fileName.substring(0, fileName.lastIndexOf(Constants.POINT));
        OpenSlide os = null;
        try {
            os = new OpenSlide(infile);
            int levelCount = os.getLevelCount();
            // 切割
            for (int n = levelCount - 1; n > -1; n--) { //n表示层级,也表示需要创建的文件夹名字
                int nHeight = (int) (os.getLevel0Height() / os.getLevelHeight(n)); //切高的次数
                int nWidth = (int) (os.getLevel0Width() / os.getLevelWidth(n)); //切长的次数
                for (int j = 0; j < nWidth; j++) {  //循环切长
                    for (int i = 0; i < nHeight; i++) {  //循环切高
                        BufferedImage th = os.createThumbnailImage((int) (j * os.getLevelWidth(n)), (int) (i * os.getLevelHeight(n)), os.getLevelHeight(n), os.getLevelHeight(n), imgSize);  //开始切图
                        // 输出文件到对应目录
                        //创建目录
                        String resultName = outfile + File.separator + n + File.separator + nameWithoutExtension + Constants.UNDERSCORE + j + Constants.UNDERSCORE + i + Constants.POINT + imgType;
                        File file = new File(outfile + File.separator + n);
                        if (!file.exists()) {
                            System.out.println("文件不存在");
                            file.mkdirs();//创建失败会抛出异常throw new IOException("Invalid file path");
                        }
                        ImageIO.write(th, imgType, new File(resultName));
                        System.out.println("保存成功:" + resultName);
                    }
                }
            }
            // 附件获取
            Map<String, AssociatedImage> map = os.getAssociatedImages();
            for (Map.Entry<String, AssociatedImage> entry : map.entrySet()) {
                BufferedImage img = entry.getValue().toBufferedImage();

                BufferedImage result = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics g = result.getGraphics();
                g.drawImage(img, 0, 0, null);
                String resultName = outfile + File.separator + nameWithoutExtension + Constants.LINE + entry.getKey() + Constants.POINT + imgType;
                // 输出文件到对应目录
                ImageIO.write(result, imgType, new File(resultName));
                resultAddress.add(resultName);
            }
            return resultAddress;
        } catch (IOException e) {
            log.error("创建OS对象失败");
            e.printStackTrace();
            return null;
        } finally {
            assert os != null;
            os.close();
        }
    }

    /**
     * cutFileToMinIo
     * 切割文件存放到minio
     * 这个用作将上传的文件进行切割保存至相关文件服务器上
     * 由于这里是上传至minio的,所以会有bucketName和directory参数,可以自行进行修改,最后进行测试  
     * @param inFile
     * @param bucketName
     * @param directory
     * @author: chong
     * @description
     * @date 2022/5/10
     */
    public MinioOpenSlideVo cutFileToMinIo(MultipartFile inFile, String bucketName, String directory) {
         // 自定义异常,可以根据自己的需要判断或者删除(相关类不进行粘贴)
        SysException.throwException(OPENSLIDE_UNAVAILABLE, ResultCodeEnum.FAIL.code(), "OpenSlide is unavailable - will be skipped");
        SysException.throwException(StringUtils.isBlank(inFile.getOriginalFilename()), ResultCodeEnum.NOT_FOUND.code(), "切割文件失败!文件不存在!--》" + inFile.getName());
        OpenSlide os = null;
        File file = null;
        MinioOpenSlideVo minioOpenSlideVo = new MinioOpenSlideVo();
        try {
            // 转换临时文件
            file = FileUtils.multipartFileToFile(inFile);
            String fileName = file.getName();
            String nameWithoutExtension = fileName.substring(0, fileName.lastIndexOf(Constants.POINT));
            os = new OpenSlide(file);
            int levelCount = os.getLevelCount();
            // 切割
            for (int n = levelCount - 1; n > -1; n--) { //n表示层级,也表示需要创建的文件夹名字
                int nHeight = (int) (os.getLevel0Height() / os.getLevelHeight(n)); //切高的次数
                int nWidth = (int) (os.getLevel0Width() / os.getLevelWidth(n)); //切长的次数
                for (int j = 0; j < nWidth; j++) {  //循环切长
                    for (int i = 0; i < nHeight; i++) {  //循环切高
                        BufferedImage image = os.createThumbnailImage((int) (j * os.getLevelWidth(n)), (int) (i * os.getLevelHeight(n)), os.getLevelHeight(n), os.getLevelHeight(n), imgSize);  //开始切图
                        // 文件名 Constants.UNDERSCORE是下划线_
                        String resultName = nameWithoutExtension + Constants.UNDERSCORE + j + Constants.UNDERSCORE + i + Constants.POINT + imgType;
                        // 文件存放位置
                        String resultPath = directory + File.separator + n + File.separator + nameWithoutExtension + Constants.UNDERSCORE + j + Constants.UNDERSCORE + i;
                        // 输出流
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        ImageIO.write(image, imgType, outputStream);
                        //转换为MultipartFile
                        MultipartFile multipartFile = new MockMultipartFile(resultName, resultName, "application/octet-stream", outputStream.toByteArray());
                        // 上传minio
                        minIoUtils.upload(multipartFile, bucketName, resultPath);
                    }
                }
            }
            // 附件获取
            Set<String> appendixes = new HashSet<>();
            Map<String, AssociatedImage> map = os.getAssociatedImages();
            for (Map.Entry<String, AssociatedImage> entry : map.entrySet()) {
                BufferedImage image = entry.getValue().toBufferedImage();

                BufferedImage result = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_RGB);
                Graphics g = result.getGraphics();
                g.drawImage(image, 0, 0, null);
                // 文件名
                String resultName = nameWithoutExtension + Constants.LINE + entry.getKey() + Constants.POINT + imgType;
                // 文件存放位置 Constants.LINE是横线-
                String resultPath = directory + File.separator + nameWithoutExtension + Constants.LINE + entry.getKey();
                // 输出流
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                ImageIO.write(image, imgType, outputStream);
                //转换为MultipartFile
                MultipartFile multipartFile = new MockMultipartFile(resultName, resultName, "application/octet-stream", outputStream.toByteArray());
                // 上传minio
                minIoUtils.upload(multipartFile, bucketName, resultPath);
                appendixes.add(entry.getKey());
            }
            log.info("文件切割成功!--》" + inFile.getOriginalFilename());
            minioOpenSlideVo.setLevelCount(levelCount);
            minioOpenSlideVo.setAppendixes(appendixes);
            return minioOpenSlideVo;
        } catch (IOException e) {
            log.error("文件切割失败!" + inFile.getOriginalFilename());
            e.printStackTrace();
            return null;
        } finally {
            // 删除临时文件
            FileUtils.deleteTempFile(file);
            assert os != null;
            os.close();
        }
    }
}

4、上面的minio是文件服务器,你可以结合自己的方式去进行处理修改,不一定大文件有附件,若无附件可以删除**// 附件获取**下方的代码

至于其他有关openslide的用法,就自己找资料吧。希望本文章能帮助你解决一下困惑。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值