java - Converting PDF to TIFF for Faxing - Stack Overflow

admin2025-04-16  2

I'm currently struggling to convert a PDF to a TIFF file that I can then fax via Asterisk.

It seems that the PDF tools library has this functionality, but it's not free. However, the documentation specifies some key settings to use:

Compression algorithm: CCITT Group 3 or CCITT Group 4 Vertical resolution: 98 DPI (Standard) or 196 DPI (High) Here's a link to the documentation: PDF Tools SDK Conversion Profiles

I've already configured these settings, and when I check the output with tiffInfo on Linux, everything seems fine. However, Asterisk still can't send the fax. Since these settings are standard for faxing and not specifically for Asterisk, I'm hoping someone can tell me what I might be missing or doing wrong.

Below is my Java code, and I'd really appreciate any guidance.

Thanks in advance!

    public static InputStream toTIFF(InputStream pdfInputStream) {
    PDDocument document = null;
    ImageOutputStream imageOutputStream = null;
    ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
    try {
        document = Loader.loadPDF(IOUtils.toByteArray(pdfInputStream));
        imageOutputStream = ImageIO.createImageOutputStream(pdfOutputStream);
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");
        ImageWriter writer = writers.next();
        writer.setOutput(imageOutputStream);
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionType("CCITT T.6");
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        writer.prepareWriteSequence(null);
        for (int pageIndex = 0; pageIndex < document.getNumberOfPages(); pageIndex++) {
            BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 98, ImageType.BINARY);
            BufferedImage bwImage = new BufferedImage(image.getWidth(), image.getHeight(),
                    BufferedImage.TYPE_BYTE_BINARY);
            Graphics2D g2d = bwImage.createGraphics();
            g2d.drawImage(image, 0, 0, Color.WHITE, null);
            g2d.dispose();
            IIOImage ioImage = new IIOImage(bwImage, null, null);
            writer.writeToSequence(ioImage, writeParam);
        }
        writer.endWriteSequence();
        writer.dispose();
        document.close();
        imageOutputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new ByteArrayInputStream(pdfOutputStream.toByteArray());
}

I'm currently struggling to convert a PDF to a TIFF file that I can then fax via Asterisk.

It seems that the PDF tools library has this functionality, but it's not free. However, the documentation specifies some key settings to use:

Compression algorithm: CCITT Group 3 or CCITT Group 4 Vertical resolution: 98 DPI (Standard) or 196 DPI (High) Here's a link to the documentation: PDF Tools SDK Conversion Profiles

I've already configured these settings, and when I check the output with tiffInfo on Linux, everything seems fine. However, Asterisk still can't send the fax. Since these settings are standard for faxing and not specifically for Asterisk, I'm hoping someone can tell me what I might be missing or doing wrong.

Below is my Java code, and I'd really appreciate any guidance.

Thanks in advance!

    public static InputStream toTIFF(InputStream pdfInputStream) {
    PDDocument document = null;
    ImageOutputStream imageOutputStream = null;
    ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
    try {
        document = Loader.loadPDF(IOUtils.toByteArray(pdfInputStream));
        imageOutputStream = ImageIO.createImageOutputStream(pdfOutputStream);
        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");
        ImageWriter writer = writers.next();
        writer.setOutput(imageOutputStream);
        ImageWriteParam writeParam = writer.getDefaultWriteParam();
        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionType("CCITT T.6");
        PDFRenderer pdfRenderer = new PDFRenderer(document);
        writer.prepareWriteSequence(null);
        for (int pageIndex = 0; pageIndex < document.getNumberOfPages(); pageIndex++) {
            BufferedImage image = pdfRenderer.renderImageWithDPI(pageIndex, 98, ImageType.BINARY);
            BufferedImage bwImage = new BufferedImage(image.getWidth(), image.getHeight(),
                    BufferedImage.TYPE_BYTE_BINARY);
            Graphics2D g2d = bwImage.createGraphics();
            g2d.drawImage(image, 0, 0, Color.WHITE, null);
            g2d.dispose();
            IIOImage ioImage = new IIOImage(bwImage, null, null);
            writer.writeToSequence(ioImage, writeParam);
        }
        writer.endWriteSequence();
        writer.dispose();
        document.close();
        imageOutputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return new ByteArrayInputStream(pdfOutputStream.toByteArray());
}
Share Improve this question edited Feb 5 at 20:26 miken32 42.8k16 gold badges125 silver badges174 bronze badges asked Feb 3 at 16:35 Imo GrafImo Graf 211 bronze badge 3
  • Because that doesn't always work. As I said, I can open the tiff file on any PC, but sending it as a fax doesn't work. I would also like to work without external libs. I have a huge web app with Java in the backend. Of course that would work and I would do it if necessary. But when I google it, other people also have problems converting it to Linux for a fax on the terminal. So the same problem again. – Imo Graf Commented Feb 3 at 18:27
  • 1 Can you describe in what way the above code doesn't work? What error message or symptoms do you see when trying to send as fax? It may also help if you add the missing link to the "Conversion Profiles" page in your question. – Harald K Commented Feb 4 at 8:45
  • Does fax transmission using Asterix require a specific byte order? Do you need an "envelope"/wrapper around the TIFF file? Or encoding as @KJ suggests? The code to generate the TIFFs seems reasonable to me. – Harald K Commented Feb 4 at 8:56
Add a comment  | 

1 Answer 1

Reset to default 0

After posting my first answer, I realized that I knew nothing about Faxing as it relates to this based on the comments. I did a little research. Hopefully, this helps. @Harald K answer is what you are looking for. T6 Compressed Tiff image

import org.apache.pdfbox.Loader;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.*;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


public class Main
{
    public static void main(String[] args)
    {
        File pdfFile = new File("path/to/pdfFile.pdf");

        List<File> tiffsFromPDF = ConvertPdfToTiff(pdfFile);

        for (File tiffFile : tiffsFromPDF) {
            CreateFaxTiff(tiffFile);
        }
    }

    public static List<File> ConvertPdfToTiff(File pdfFile)
    {
        List<File> outputFileList = new ArrayList<>();

        try
        {
            PDDocument document = Loader.loadPDF(pdfFile);
            PDFRenderer pdfRenderer = new PDFRenderer(document);

            int numberOfPages = document.getNumberOfPages();
            for(int i = 0; i < numberOfPages; i++)
            {
                BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(i, 196);
                File outputFile = new File("ouput/path/image " + i + ".tiff");
                ImageIO.write(bufferedImage, "tiff", outputFile);
                outputFileList.add(outputFile);
            }

        }
        catch (IOException e)
        {
            System.out.println(e.toString());
        }

        return outputFileList;
    }

    public static void CreateFaxTiff(File tiffFile) {
        try
        {
            BufferedImage bufferedImage = convertToBinary(ImageIO.read(tiffFile));

            String outputFileName = tiffFile.getName().substring(0,tiffFile.getName().indexOf(".")) + "_output.tiff";
            String outputFilePath = tiffFile.getParent();
            File outputFile = new File(outputFilePath + "/" + outputFileName);
            outputFile.createNewFile();
            System.out.println(outputFile.toString());

            ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputFile);
            ImageTypeSpecifier imageTypeSpecifier = ImageTypeSpecifier.createFromRenderedImage(bufferedImage);
            javax.imageio.ImageWriter tiffWriter = ImageIO.getImageWriters(imageTypeSpecifier, "TIFF").next();
            tiffWriter.setOutput(imageOutputStream);

            ImageWriteParam imageWriteParam = tiffWriter.getDefaultWriteParam();
            imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
            //Arrays.stream(imageWriteParam.getCompressionTypes()).sequential().forEach(System.out::println);
            imageWriteParam.setCompressionType("CCITT T.4");

            IIOMetadata iioMetadata = tiffWriter.getDefaultImageMetadata(imageTypeSpecifier, imageWriteParam);
            IIOImage iioImage = new IIOImage(bufferedImage, null, iioMetadata);

            tiffWriter.write(null, iioImage, imageWriteParam);

            imageOutputStream.close();
            tiffWriter.dispose();

        }
        catch (IOException ex)
        {
            System.out.println(ex.toString());
        }
    }

    public static BufferedImage convertToBinary(Image image) {
        int width = image.getWidth(null);
        int height = image.getHeight(null);

        // Create a new BufferedImage with the desired type
        BufferedImage binaryImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY);

        // Draw the original image onto the new BufferedImage
        Graphics2D g2d = binaryImage.createGraphics();
        g2d.drawImage(image, 0, 0, null);
        g2d.dispose();

        return binaryImage;
    }
}
转载请注明原文地址:http://www.anycun.com/QandA/1744760975a87239.html