kfb格式文件转jpg格式

        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;
import java.util.concurrent.TimeUnit;

/**
 * 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);
                //计算大约需要多少秒
                int seconds = fileSize.divide(new BigDecimal(10), 2, RoundingMode.HALF_UP).intValue();

                String tifPath = kfbPath.substring(0, kfbPath.lastIndexOf(".")) + extensionName;
                String[] cmd = new String[]{"cmd", "/c", exePath + " \"" + kfbPath + "\" \"" + tifPath + "\" 3"};
                // 执行自动备份任务
                Process process = Runtime.getRuntime().exec(cmd);
                process.waitFor(seconds, TimeUnit.SECONDS);
                process.destroy();
            }
        }.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.*;

public class Tif2Jpg {

    /**
     * @param fileAbsolutePath
     * @param seconds          执行前休眠秒数
     * @throws InterruptedException
     */
    public static void tif2Jpg(String fileAbsolutePath, int seconds) throws InterruptedException {
        Thread.sleep(1000 * seconds);
        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++) {
            //此处不能从0开始,否则报错(只取最前面两张图)
            for (int i = 1; i < 3; i++) {
                RenderedImage renderedImage = dec.decodeAsRenderedImage(i);
                String isMin = i == 1 ? "_min" : "";
                File imgFile = new File(filePathPrefix + isMin + ".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", 1);
//        jpg2Tif("D:/upload/2022/02/21/222.jpg");
    }
}

         tif中可能会包含多张图片,我这边所使用的kfb转换成的tif中至少都有5张图片(第一张是病理文件的小标签,后续开始才是正图)。代码对于你们所用的业务可能不够完善,自行完善。上述代码是满足我这边业务的,我代码中就是那个代码。

        代码中使用了线程休眠,原因在于tif转jpg时,假如tif转换还没有完成时,此刻你调用了tif转jpg就会失败,所有才使用了休眠。如果你不需要,可以去除线程休眠相关代码。

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

        
            javax.media
            jai_codec
            1.1.3
        
        
            javax.media
            jai_core
            1.1.3
        

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

到此,kfb转jpg已经完成!

你可能感兴趣的:(其他,Java,java,kfb转tif或svs,kfb转jpg,tif转jpg)