首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >T6压缩Tiff图像

T6压缩Tiff图像
EN

Stack Overflow用户
提问于 2020-04-05 10:30:56
回答 1查看 1.3K关注 0票数 0

我正在尝试读取JPG格式的图像文件,将文本写入图像,并将其保存到单个条状压缩的TIFF图像格式中。我使用对输出图像文件进行压缩和写入。我不知道为什么输出图像被分割成两部分,第二部分是第一部分。如果有人能帮我解决这个问题或者指出我在这里做错了什么。谢谢..

这是来自下面代码的示例输入和输出图像..。

样本图像

代码语言:javascript
复制
FileOutputStream      fos  = null;
BufferedOutputStream  os   = null;
ByteArrayOutputStream baos = null;

try {

    String          inputPath    = "D:\\Test\\input.jpg";
    File            inputFile    = new File(inputPath);

    BufferedImage   inputImage   = ImageIO.read(inputFile);

    int             width        = inputImage.getWidth();
    int             height       = inputImage.getHeight();

    BufferedImage   outputImage  = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);

    Font font = new Font("Arial", Font.BOLD, 40 );
    java.awt.Graphics2D g2 = outputImage.createGraphics();
    g2.setFont( font );
    g2.setColor ( Color.BLACK );
    g2.drawImage ( inputImage, 0, 0, width, height, Color.WHITE, null);
    g2.drawString("TEST TEXT", 20, 40);
    g2.dispose();

    PixelDensity        resolution   = PixelDensity.createFromPixelsPerInch ( 200, 200);
    double              resolutionX  = resolution.horizontalDensityInches();
    double              resolutionY  = resolution.verticalDensityInches();
    RationalNumber      rationalNumX = RationalNumber.valueOf ( resolutionX );
    RationalNumber      rationalNumY = RationalNumber.valueOf ( resolutionY );

    TiffOutputSet       outputSet    = new TiffOutputSet(ByteOrder.LITTLE_ENDIAN);
    TiffOutputDirectory directory    = outputSet.addRootDirectory();

    baos = new ByteArrayOutputStream(); 
    ImageIO.write(outputImage, "tif", baos); 
    byte[] bytes = baos.toByteArray();

    byte[] compressedBytes = T4AndT6Compression.compressT6(bytes, width, height);

    TiffImageData.Data data = new TiffImageData.Data(0, compressedBytes.length, compressedBytes);

    TiffElement.DataElement[] dataElements = new TiffElement.DataElement[]{ data };

    TiffImageData tiffImageData = new TiffImageData.Strips(dataElements, height);

    directory.add ( TiffTagConstants.TIFF_TAG_NEW_SUBFILE_TYPE,                   1    );
    directory.add ( TiffTagConstants.TIFF_TAG_PHOTOMETRIC_INTERPRETATION, (short) 1    );
    directory.add ( TiffTagConstants.TIFF_TAG_COMPRESSION,                (short) 4    );
    directory.add ( TiffTagConstants.TIFF_TAG_BITS_PER_SAMPLE,            (short) 1    );
    directory.add ( TiffTagConstants.TIFF_TAG_RESOLUTION_UNIT,            (short) 2    );
    directory.add ( TiffTagConstants.TIFF_TAG_ROWS_PER_STRIP,             height       );
    directory.add ( TiffTagConstants.TIFF_TAG_IMAGE_WIDTH,                width        );
    directory.add ( TiffTagConstants.TIFF_TAG_IMAGE_LENGTH,               height       );
    directory.add ( TiffTagConstants.TIFF_TAG_XRESOLUTION,                rationalNumX );
    directory.add ( TiffTagConstants.TIFF_TAG_YRESOLUTION,                rationalNumY );

    directory.setTiffImageData( tiffImageData );

    String outputPath = "D:\\Test\\output.tif";
    File outputFile = new File(outputPath);

    fos = new FileOutputStream(outputFile);
    os   = new BufferedOutputStream(fos);

    new TiffImageWriterLossy().write( os, outputSet );


} catch (IOException ex) {

    Logger.getLogger(JavaApplication7.class.getName()).log(Level.SEVERE, null, ex);

}   catch (ImageWriteException ex) {

    Logger.getLogger(JavaApplication7.class.getName()).log(Level.SEVERE, null, ex);

} finally {

    if ( baos != null ) {
        try { 
            baos.flush();   
            baos.close();   
        } catch ( IOException ex ) { }
    }
    if ( os != null ) {
        try { 
            os.flush();   
            os.close();   
        } catch ( IOException ex ) { }
    }
    if ( fos != null ) {
        try { 
            fos.flush();   
            fos.close();   
        } catch ( IOException ex ) { }
    }

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-06 07:58:50

代码的问题是,您首先使用BufferedImage将TIFF文件存储为TIFF文件,然后将整个文件与头一起压缩为您传递给共用映像的图像的像素数据:

代码语言:javascript
复制
baos = new ByteArrayOutputStream(); 
ImageIO.write(outputImage, "tif", baos); 
byte[] bytes = baos.toByteArray(); // <-- This is not pixel data, but a complete TIFF file

byte[] compressedBytes = T4AndT6Compression.compressT6(bytes, width, height);

这实际上类似于您所期望的图像,原因是ImageIO写入的图像数据未压缩。在图像之前的垃圾行和偏移量,是TIFF头和标记显示为像素.

相反,您可能打算做这样的事情:

代码语言:javascript
复制
// Cast is safe here, as you know outputImage is TYPE_BYTE_BINARY
byte[] bytes = ((DataBufferByte) outputImage.getRaster().getDataBuffer()).getData();
byte[] compressedBytes = T4AndT6Compression.compressT6(bytes, width, height);

这只会压缩像素,你的图像应该会很好。

您还可以只使用ImageIO完成任何事情,并通过这样的操作避免对共用映像的额外依赖:

代码语言:javascript
复制
try (ImageOutputStream stream = ImageIO.createImageOutputStream(outputFile)) {
    ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromRenderedImage(outputImage);
    ImageWriter writer = ImageIO.getImageWriters(imageTypeSpecifier, "TIFF").next();
    writer.setOutput(stream);

    ImageWriteParam param = writer.getDefaultWriteParam();
    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
    param.setCompressionType("CCITT T.6");

    IIOMetadata metadata = writer.getDefaultImageMetadata(imageTypeSpecifier, param);
    // TODO: Set 200 DPI, default is likely 72, and perhaps subfile type if needed, 
    // other tags will be set correctly for you

    writer.write(null, new IIOImage(outputImage, null, metadata), param);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61041199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档