kfb格式文件转jpg格式

10 篇文章 0 订阅

        KFB格式的全视野数字病理切片(Whole slide images, WSIs)是国内一种病理切片扫描仪扫描出来的私有格式,该扫描仪是宁波江丰生物信息技术有限公司的一款产品。

        然而,在实际开发中我们是无法直接使用该格式的文件。另外kfb文件大小不一,小的几十MB,大的甚至几个G,这么大的文件打开都是问题。

       网上搜索各种资料,各种尝试,甚至AI都找了,AI写的代码是各种问题,不是找不见maven依赖就是代码执行各种报错。真的是各种屡试不爽,前前后后折腾了一个礼拜。最终经过本人多次研究尝试,找到了解决方案(转jpg)。

1. 按照网上说的最多的方法来进行第一步操作(kfb转tif)

        相关代码如下:

package com.lonzh.utils;

import lombok.SneakyThrows;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * Kfb转成其他格式
 *
 * @author DaiHaijiao
 */
public class Kfb2Other {

    public static final String TIF = ".tif";
    public static final String SVS = ".svs";

    /**
     * 转换(性能一般的SSD磁盘 转换200Mb的文件大约需要20s)
     *
     * @param exePath
     * @param kfbPath
     * @param extensionName 拓展名
     */
    public static void convert(String exePath, String kfbPath, String extensionName) {
        new Thread() {
            @SneakyThrows
            @Override
            public void run() {
                BigDecimal decimal = new BigDecimal(1024);
                //文件大小,单位:MB
                BigDecimal fileSize = new BigDecimal(new File(kfbPath).length()).divide(decimal, 2, RoundingMode.HALF_UP).divide(decimal, 2, RoundingMode.HALF_UP);


                String tifPath = kfbPath.substring(0, kfbPath.lastIndexOf(".")) + extensionName;
                String[] cmd = new String[]{"cmd", "/c", exePath + " \"" + kfbPath + "\" \"" + tifPath + "\" 3"};
                // 执行自动备份任务
                Process process = Runtime.getRuntime().exec(cmd);
                if (process.waitFor() == 0) {
                    process.destroy();
                    Tif2Jpg.tif2Jpg(tifPath);
                }
            }
        }.start();
    }

    public static void main(String[] args) {
        String exePtah = "C:\\病理教学软件\\kfb2tif\\KFB转Tif或SVS工具2.0\\x86\\KFbioConverter.exe";
        convert(exePtah, "D:\\pathology-teaching\\file\\顶级目录\\骨/BL-01-01_骨骼肌萎缩-202306160841479.kfb", Kfb2Other.TIF);
    }

}

        代码中有使用到“KFbioConverter.exe”,假如你有C币,请移步传送门进行下载。假如你没有C币,就自行百度吧(就是花点时间的事)。

        注意:“KFbioConverter.exe”不要安装,是通过代码调用执行的文件类型转换!!!

        上述代码中是kfb转tif,假如你需要转svs,也可转svs,后续的转jpg是基于tif格式进行的转换。

2. tif转jpg

关键代码

package com.lonzh.utils;

import com.sun.media.jai.codec.*;

import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.*;

/**
 * Tif装图片
 *
 * @author DaiHaijiao
 */
public class Tif2Jpg {

    /**
     * @param fileAbsolutePath
     * @throws InterruptedException
     */
    public static void tif2Jpg(String fileAbsolutePath) {
        if (fileAbsolutePath == null || "".equals(fileAbsolutePath.trim())) {
            return;
        }
        if (!new File(fileAbsolutePath).exists()) {
            System.out.println("系统找不到指定文件【" + fileAbsolutePath + "】");
            return;
        }
        FileSeekableStream fileSeekStream = null;
        try {
            fileSeekStream = new FileSeekableStream(fileAbsolutePath);
            TIFFEncodeParam tiffEncodeParam = new TIFFEncodeParam();
            JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
            ImageDecoder dec = ImageCodec.createImageDecoder("tiff", fileSeekStream, null);
            int count = dec.getNumPages();
            tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
            tiffEncodeParam.setLittleEndian(false);
            System.out.println("该tif文件共有" + count + "页");
            String filePathPrefix = fileAbsolutePath.substring(0,             fileAbsolutePath.lastIndexOf("."));
            for (int i = 0; i < count; i++) {
                RenderedImage renderedImage = dec.decodeAsRenderedImage(i);
                String str = "";
                if (i == 0) {
                    //最大的一张图
                    str = "_large_img";
                } else if (i == 4) {
                    //玻璃片上的标签
                    str = "_slide_label";
                } else if (i == 5) {
                    //玻璃片
                    str = "_slide";
                } else if (i == 1) {
                    //缩略图 i=1 和 i=3 图大小几乎无异,像素都是一样的,此处取略小的作为缩略图
                    str = "_small_img";
                } else if (i == 2) {
                    //大小和像素都介于最大图和缩略图之间的图
                    str = "_medium_img";
                } else {
                    continue;
                }
                File imgFile = new File(filePathPrefix + str + ".jpg");
                System.out.println("第" + i + "页保存至: " + imgFile.getCanonicalPath());
                ParameterBlock pb = new ParameterBlock();
                pb.addSource(renderedImage);
                pb.add(imgFile.toString());
                pb.add("JPEG");
                pb.add(jpegEncodeParam);
                RenderedOp renderedOp = JAI.create("filestore", pb);
                renderedOp.dispose();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileSeekStream != null) {
                try {
                    fileSeekStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void jpg2Tif(String fileAbsolutePath) {
        OutputStream outputStream = null;
        try {
            RenderedOp renderOp = JAI.create("fileload", fileAbsolutePath);
            String tifFilePath = fileAbsolutePath.substring(0, fileAbsolutePath.lastIndexOf(".")) + ".tif";
            outputStream = new FileOutputStream(tifFilePath);
            TIFFEncodeParam tiffParam = new TIFFEncodeParam();
            ImageEncoder imageEncoder = ImageCodec.createImageEncoder("TIFF", outputStream, tiffParam);
            imageEncoder.encode(renderOp);
            System.out.println("jpg2Tif 保存至: " + tifFilePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

//    public static void main(String args[]) throws InterruptedException {
//        tif2Jpg("C:\\pathology-teaching\\file\\顶级目录\\心/BL-15-04_肝包虫病-202306131413433.tif");
//        jpg2Tif("D:/upload/2022/02/21/222.jpg");
//    }
}

         tif中可能会包含多张图片,我这边所使用的kfb转换成的tif中有5张图片。代码对于你们所用的业务可能不够完善,自行完善。上述代码是满足我这边业务的,我代码中就是那个代码。

        注意:当tif图文件过大时,获取tif中最大的那一张图会报错!!!

        针对于获取最大的那一张图报错问题,后面的帖子会继续讲述关于那一张最大的图的处理办法!

        上述代码需要在pom文件中引入相关依赖

        <dependency>
            <groupId>javax.media</groupId>
            <artifactId>jai_codec</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>javax.media</groupId>
            <artifactId>jai_core</artifactId>
            <version>1.1.3</version>
        </dependency>

有C币的朋友可直接移步jar文件下载传送门(jar引入方式见:本地Maven仓库导入外部jar

到此,kfb转jpg已经完成!

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值