无法强制转换Java rawImageInputStream-imageIO

无法强制转换Java rawImageInputStream-imageIO,java,javax.imageio,dcm4che,Java,Javax.imageio,Dcm4che,我正在做一个图像转换器,它将DICOM格式的图像转换成PNG格式 @SuppressWarnings("restriction") public void dcmconvpng(File file, int indice, File fileOutput) throws IOException { ImageIO.scanForPlugins(); Iterator<ImageReader> iter =

我正在做一个图像转换器,它将DICOM格式的图像转换成PNG格式

@SuppressWarnings("restriction")
    public void dcmconvpng(File file, int indice, File fileOutput)
            throws IOException {        
        ImageIO.scanForPlugins();
        Iterator<ImageReader> iter = ImageIO
                .getImageReadersByFormatName("DICOM");
        ImageReader readers = (ImageReader) iter.next();
        DicomImageReadParam param = (DicomImageReadParam) readers
                .getDefaultReadParam();

        ImageInputStream iis = ImageIO.createImageInputStream(file);
        readers.setInput(iis, true);
        myPngImage = readers.read(indice, param);
        BufferedImage dimg = myPngImage;

        File myPngFile = fileOutput;
        OutputStream output = new BufferedOutputStream(new FileOutputStream(
                myPngFile));
        PNGEncodeParam.RGB param2 = new PNGEncodeParam.RGB();
        ImageEncoder enc = ImageCodec.createImageEncoder("PNG", output, param2);
        enc.encode(dimg);
        output.close();
        System.out.println("Conversion has been completed!");

    }
我很确定这是因为我的项目中有多个imageIO JAR,请提供帮助

我很确定这是因为我的项目中有多个imageIO JAR

恰到好处

问题似乎是,
DicomImageReader
创建了一个新的
rawmageinputstream
(来自
com.sun.media.imageio.stream
),但在RAW
图像阅读器上进行了查找:

RawImageInputStream riis = new RawImageInputStream(...)
...
reader = ImageIO.getImageReadersByFormatName("RAW").next();
reader.setInput(riis);
(代码取自)

由于您的两个JAR都包含用于读取原始图像的服务提供者(SPI),并且默认情况下没有特定的顺序,
ImageReader
DicomImageReader
在运行时使用的实际
。从长远来看,最好的解决方案可能是更新
DicomImageReader
,以确保获得正确的
RawImageReader
(与输入兼容),但集成这样的更改通常需要更多的时间,因此我将在下面概述一种解决方法

您在项目中需要两个JAR,但如果不需要两个JAR中的原始图像读取器,可以从
com.github.jaimageio
包中注销该读取器

看。这个问题中的SPI是针对TIFF格式的,但概念是相同的。您应该注销
com.github.jaimageio.impl.plugins.raw.rawmagereaderspi
,或者确保先订购
com.sun.media.imageio.impl.plugins.raw.rawmagereaderspi


通过编辑
META-INF/services/
文件夹中的条目,还可以阻止JAR中的SPI注册。应该有一个META-INF/services/javax.imageio.spi.ImageReaderSpi的条目,您应该删除或注释掉
com.github.jaimageIO.impl.plugins.raw.rawmageReaderSpi
最终放弃了整个代码块,并使用了以下库:

  • pixelmed.jar
  • vecmath-1.5.2.jar
并使用以下代码:

public void dcmconvpng(File file, int indice, File fileOutput)
        throws IOException, DicomException {

    ConsumerFormatImageMaker.convertFileToEightBitImage(file.toString(),
            fileOutput.toString(), "png", indice);
}

它确实做了同样的事情,只是简单得多。

我注意到它只转换了3张图像,但仅此而已。嗨,haraldK,谢谢你的回复。我试图实现你在另一篇文章中提供的方法,但没有成功,并且继续得到同样的错误。然后我把你建议的行注释掉了,程序仍然继续产生同样的错误。只是一些背景。如果库jai-imageio-core-1.3.1.jar保留jai_-imageio-1.1.jar,我的转换器会运行,但是我的另一个需要imageio的方法会产生错误:
NoClassDefFoundError:com/github/jaimageIO/plugins/tiff/TIFFImageWriteParam
你是在web容器中运行应用程序吗?不,我不是,我只是在使用一个普通的Java控制台应用程序。这是我的回购协议。隐马尔可夫模型。。。我很有信心,如果实施得当,我建议的变通方法会奏效。可能是
ImageIO.scanForPlugins()
重新添加了提供程序,或者有更多麻烦的提供程序。但如果你找到了另一种解决方法,我就不谈了。:-)
public void dcmconvpng(File file, int indice, File fileOutput)
        throws IOException, DicomException {

    ConsumerFormatImageMaker.convertFileToEightBitImage(file.toString(),
            fileOutput.toString(), "png", indice);
}