Java JAI Tiff到JPEG的转换问题

Java JAI Tiff到JPEG的转换问题,java,jpeg,tiff,jai,Java,Jpeg,Tiff,Jai,我在使用JAI将Tiff文件转换为JPEG时遇到问题。这是我的代码: ByteArrayOutputStream=newbytearrayoutputstream(); TIFFDecodeParam param=null; ImageDecoder dec=ImageCodec.createImageDecoder(“tiff”,新文件seekablestream(inPath),param); RenderImageOp=dec.DecodeAsRenderImage0; JPEGEncod

我在使用JAI将Tiff文件转换为JPEG时遇到问题。这是我的代码:

ByteArrayOutputStream=newbytearrayoutputstream();
TIFFDecodeParam param=null;
ImageDecoder dec=ImageCodec.createImageDecoder(“tiff”,新文件seekablestream(inPath),param);
RenderImageOp=dec.DecodeAsRenderImage0;
JPEGEncodeParam jpgparam=新的JPEGEncodeParam();
jpgparam.setQuality(67);
ImageEncoder en=ImageCodec.createImageEncoder(“jpeg”,BAS,jpgparam);
编码(op);
这段代码基本上可以正常工作,但对于一些图像,我得到了以下错误:

java.lang.RuntimeException: Only 1, or 3-band byte data may be written.
at com.sun.media.jai.codecimpl.JPEGImageEncoder.encode(JPEGImageEncoder.java:142)
我在这里找不到任何相关问题,也不知道如何解决。抛出此错误的图像具有高分辨率(9000 x 7000或更高),并且大多是旧图片的扫描

此颜色模型的图像适用于:

ColorModel: 
#pixelBits = 24 
numComponents = 3 
color space = java.awt.color.ICC_ColorSpace@21981a50 
transparency = 1 has alpha = false 
isAlphaPre = false
这不是:

ColorModel: 
#pixelBits = 16 
numComponents = 1 
color space = java.awt.color.ICC_ColorSpace@88a30ad 
transparency = 1 has alpha = false 
isAlphaPre = false

我试着阅读JPEG标准,但不清楚这是JPEG格式的限制还是编码器的限制

java提供的编码器只编码1或3个字节带,因此在您的示例中有16位灰度图像。解决这个问题的一种方法是使用PNG编码器保存图像,正如您所做的那样。它不支持压缩质量参数

另一种处理方法是将图像保存为8位灰度图像

我做了一个简单的例子来测试这个w/out-JAI

public static void main(String[] args) throws Exception{
        BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_USHORT_GRAY);
        Iterator<ImageWriter> writers = ImageIO.getImageWritersBySuffix("jpg");
        while( writers.hasNext() ){
            ImageWriter writer = writers.next();
            ImageOutputStream ios = ImageIO.createImageOutputStream( new File("junk.jpg") );
            writer.setOutput(ios);
            writer.write(img);
        }     
    }

然后,
img2
可以另存为JPG。

我尝试阅读JPEG标准,但不清楚这是JPEG格式的限制还是编码器的限制

java提供的编码器只编码1或3个字节带,因此在您的示例中有16位灰度图像。解决这个问题的一种方法是使用PNG编码器保存图像,正如您所做的那样。它不支持压缩质量参数

另一种处理方法是将图像保存为8位灰度图像

我做了一个简单的例子来测试这个w/out-JAI

public static void main(String[] args) throws Exception{
        BufferedImage img = new BufferedImage(256, 256, BufferedImage.TYPE_USHORT_GRAY);
        Iterator<ImageWriter> writers = ImageIO.getImageWritersBySuffix("jpg");
        while( writers.hasNext() ){
            ImageWriter writer = writers.next();
            ImageOutputStream ios = ImageIO.createImageOutputStream( new File("junk.jpg") );
            writer.setOutput(ios);
            writer.write(img);
        }     
    }

然后
img2
可以保存为JPG。

我已经检查了一些图像。每个人都有16位的颜色深度。getNumComponent在任何图像1上返回任何图像,这意味着任何失败的图像都有一个波段。其他TIF(正常工作)有一个3波段彩色模型。哦,我想我看到了问题,1或3字节波段。16位单通道图像将是占用1个字节以上的单波段。我不确定这是否是jpeg或您使用的编码器的故障。我检查了一些图像。每个人都有16位的颜色深度。getNumComponent在任何图像1上返回任何图像,这意味着任何失败的图像都有一个波段。其他TIF(正常工作)有一个3波段彩色模型。哦,我想我看到了问题,1或3字节波段。16位单通道图像将是占用1个字节以上的单波段。我不确定这是否是jpeg或您使用的编码器的故障。