Проблема с вашим кодом заключается в том, что вы сначала сохраняете BufferedImage
в виде файла TIFF с помощью ImageIO, а затем сжимаете весь файл вместе с заголовками в качестве данных пикселей изображения, которое вы передаете в систему обработки изображений общего пользования. :
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);
}