title: Converting PDF to multipage tiff (Group 4)
body: <p>I'm trying to convert PDFs as represented by the org.apache.pdfbox.pdmodel.PDDocument class and the icafe library (<a href="https://github.com/dragon66/icafe/" rel="nofollow">https://github.com/dragon66/icafe/</a>) to a multipage tiff with group 4 compression and 300 dpi. The sample code works for me for 288 dpi but strangely NOT for 300 dpi, the exported tiff remains just white. Has anybody an idea what the issue is here?</p>
  
  <p>The sample pdf which I use in the example is located here: <a href="http://www.bergophil.ch/a.pdf" rel="nofollow">http://www.bergophil.ch/a.pdf</a></p>
  
  <pre><code>import java.awt.image.BufferedImage;
  import java.io.FileOutputStream;
  import java.io.IOException;
  
  import org.apache.pdfbox.pdmodel.PDDocument;
  import org.apache.pdfbox.pdmodel.PDPage;
  
  import cafe.image.ImageColorType;
  import cafe.image.ImageParam;
  import cafe.image.options.TIFFOptions;
  import cafe.image.tiff.TIFFTweaker;
  import cafe.image.tiff.TiffFieldEnum.Compression;
  import cafe.io.FileCacheRandomAccessOutputStream;
  import cafe.io.RandomAccessOutputStream;
  
  public class Pdf2TiffConverter {
      public static void main(String[] args) {
          String pdf = "a.pdf";
          PDDocument pddoc = null;
          try {
              pddoc = PDDocument.load(pdf);
          } catch (IOException e) {
          }
  
          try {
              savePdfAsTiff(pddoc);
          } catch (IOException e) {
          }
      }
  
      private static void savePdfAsTiff(PDDocument pdf) throws IOException {
          BufferedImage[] images = new BufferedImage[pdf.getNumberOfPages()];
          for (int i = 0; i &lt; images.length; i++) {
              PDPage page = (PDPage) pdf.getDocumentCatalog().getAllPages()
                      .get(i);
              BufferedImage image;
              try {
  //              image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 288); //works
                  image = page.convertToImage(BufferedImage.TYPE_INT_RGB, 300); // does not work
                  images[i] = image;
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
  
          FileOutputStream fos = new FileOutputStream("a.tiff");
          RandomAccessOutputStream rout = new FileCacheRandomAccessOutputStream(
                  fos);
          ImageParam.ImageParamBuilder builder = ImageParam.getBuilder();
          ImageParam[] param = new ImageParam[1];
          TIFFOptions tiffOptions = new TIFFOptions();
          tiffOptions.setTiffCompression(Compression.CCITTFAX4);
          builder.imageOptions(tiffOptions);
          builder.colorType(ImageColorType.BILEVEL);
          param[0] = builder.build();
          TIFFTweaker.writeMultipageTIFF(rout, param, images);
          rout.close();
          fos.close();
      }
  }
  </code></pre>
  
  <p>Or is there another library to write multi-page TIFFs?</p>
  
  <p>EDIT:</p>
  
  <p>Thanks to dragon66 the bug in <code>icafe</code> is now fixed. In the meantime I experimented with other libraries and also with invoking <code>ghostscript</code>. As I think <code>ghostscript</code> is very reliable as id is a widely used tool, on the other hand I have to rely that the user of my code has an <code>ghostscript-installation</code>, something like this:</p>
  
  <pre><code>   /**
   * Converts a given pdf as specified by its path to an tiff using group 4 compression
   *
   * @param pdfFilePath The absolute path of the pdf
   * @param tiffFilePath The absolute path of the tiff to be created
   * @param dpi The resolution of the tiff
   * @throws MyException If the conversion fails
   */
  private static void convertPdfToTiffGhostscript(String pdfFilePath, String tiffFilePath, int dpi) throws MyException {
      // location of gswin64c.exe
      String ghostscriptLoc = context.getGhostscriptLoc();
  
      // enclose src and dest. with quotes to avoid problems if the paths contain whitespaces
      pdfFilePath = "\"" + pdfFilePath + "\"";
      tiffFilePath = "\"" + tiffFilePath + "\"";
  
      logger.debug("invoking ghostscript to convert {} to {}", pdfFilePath, tiffFilePath);
      String cmd = ghostscriptLoc + " -dQUIET -dBATCH -o " + tiffFilePath + " -r" + dpi + " -sDEVICE=tiffg4 " + pdfFilePath;
      logger.debug("The following command will be invoked: {}", cmd);
  
      int exitVal = 0;
      try {
          exitVal = Runtime.getRuntime().exec(cmd).waitFor();
      } catch (Exception e) {
          logger.error("error while converting to tiff using ghostscript", e);
          throw new MyException(ErrorMessages.GHOSTSTSCRIPT_ERROR, e);
      }
      if (exitVal != 0) {
          logger.error("error while converting to tiff using ghostscript, exitval is {}", exitVal);
          throw new MyException(ErrorMessages.GHOSTSTSCRIPT_ERROR);
      }
  }
  </code></pre>
  
  <p>I found that the produced <code>tif</code> from <code>ghostscript</code> strongly differs in quality from the <code>tiff</code> produced by <code>icafe</code> (the group 4 <code>tiff</code> from <code>ghostscript</code> looks greyscale-like)</p>