我正在尝试读取JPG格式的图像文件,将文本写入图像,并将其保存到单个条状压缩的TIFF图像格式中。我使用对输出图像文件进行压缩和写入。我不知道为什么输出图像被分割成两部分,第二部分是第一部分。如果有人能帮我解决这个问题或者指出我在这里做错了什么。谢谢..
这是来自下面代码的示例输入和输出图像..。
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 ) { }
}
}发布于 2020-04-06 07:58:50
代码的问题是,您首先使用BufferedImage将TIFF文件存储为TIFF文件,然后将整个文件与头一起压缩为您传递给共用映像的图像的像素数据:
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头和标记显示为像素.
相反,您可能打算做这样的事情:
// 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完成任何事情,并通过这样的操作避免对共用映像的额外依赖:
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);
}https://stackoverflow.com/questions/61041199
复制相似问题