Uploaded image for project: 'PDFBox'
  1. PDFBox
  2. PDFBOX-5171

Slow PDColorSpace.toRGBImageAWT when processing many pixel sized chuncks

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Duplicate
    • Affects Version/s: None
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      The attached PDF has a table which is embedded as an image.

      This image is processed in PDColorSpace.toRGBImageAWT(...) as
      many little chuncks of mostly 1x1 or 2x1 pixels and takes very long.
      When changing the function from a ColorConvertOp to drawing this is much faster (~2s vs. ~60s). It seems for many small images the ColorConvertOp has a big overhead.

      So I propose to change the implementation to:

          protected BufferedImage toRGBImageAWT(WritableRaster raster, ColorSpace colorSpace)
          {
              //
              // WARNING: this method is performance sensitive, modify with care!
              //
      
              // ICC Profile color transforms are only fast when performed using ColorConvertOp
              ColorModel colorModel = new ComponentColorModel(colorSpace, false, false,
                      Transparency.OPAQUE, raster.getDataBuffer().getDataType());
      
              BufferedImage src = new BufferedImage(colorModel, raster, false, null);
              BufferedImage dest = new BufferedImage(raster.getWidth(), raster.getHeight(),
                      BufferedImage.TYPE_INT_RGB);
              Graphics2D g2d = (Graphics2D) dest.getGraphics();
              g2d.drawImage(src, 0, 0, null);
              g2d.dispose();
      
              return dest;
          }
      

      or

          protected BufferedImage toRGBImageAWT(WritableRaster raster, ColorSpace colorSpace)
          {
              //
              // WARNING: this method is performance sensitive, modify with care!
              //
      
              // ICC Profile color transforms are only fast when performed using ColorConvertOp
              ColorModel colorModel = new ComponentColorModel(colorSpace, false, false,
                      Transparency.OPAQUE, raster.getDataBuffer().getDataType());
      
              BufferedImage src = new BufferedImage(colorModel, raster, false, null);
              BufferedImage dest = new BufferedImage(raster.getWidth(), raster.getHeight(),
                      BufferedImage.TYPE_INT_RGB);
              if (src.getWidth() > 1 && src.getHeight() > 1)
              {
                  ColorConvertOp op = new ColorConvertOp(null);
                  op.filter(src, dest);
              }
              else
              {
                  Graphics2D g2d = (Graphics2D) dest.getGraphics();
                  g2d.drawImage(src, 0, 0, null);
                  g2d.dispose();
              }
              return dest;
          }
      

      if the ColorConvertOp is still faster in the normal case.

        Attachments

        1. EloPdfPrint_20210420132413502.pdf
          194 kB
          Oliver Schmidtmer

          Issue Links

            Activity

              People

              • Assignee:
                Unassigned
                Reporter:
                Schmidor Oliver Schmidtmer
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: