docusealco/docuseal · error · Pdfium::PdfiumError

Failed to get image bitmap

Error message

Failed to get image bitmap

What it means

Raised by extract_image_bitmap when FPDFImageObj_GetBitmap returns NULL for an image object during image redaction. pdfium could not decode the image, which is common for JBIG2 or JPX (JPEG2000) encoded scans, corrupt image streams, or image masks that cannot be rasterized into a standard bitmap. There is no check_last_error; this is a hard stop for pixel-level redaction of that image.

Source

Thrown at lib/pdfium.rb:1454

        matrix = matrix_ptr.read_array_of_float(6)

        next if ((matrix[0] * matrix[3]) - (matrix[1] * matrix[2])).abs < 1e-9

        bitmap = extract_image_bitmap(object_ptr)
        pixel_rects = image_pixel_rects(matrix, bitmap[:width], bitmap[:height], overlapping)

        next if pixel_rects.empty?

        jpeg = yield(bitmap, pixel_rects)

        load_image_jpeg(object_ptr, jpeg) if jpeg
      end
    end

    def extract_image_bitmap(object_ptr)
      bitmap_ptr = Pdfium.FPDFImageObj_GetBitmap(object_ptr)

      raise PdfiumError, 'Failed to get image bitmap' if bitmap_ptr.nil? || bitmap_ptr.null?

      format, bands = BITMAP_FORMAT_BANDS[Pdfium.FPDFBitmap_GetFormat(bitmap_ptr)]

      raise PdfiumError, 'Unsupported image bitmap format' if format.nil?

      image_width = Pdfium.FPDFBitmap_GetWidth(bitmap_ptr)
      image_height = Pdfium.FPDFBitmap_GetHeight(bitmap_ptr)
      stride = Pdfium.FPDFBitmap_GetStride(bitmap_ptr)

      data = Pdfium.FPDFBitmap_GetBuffer(bitmap_ptr).read_bytes(stride * image_height)

      row_size = image_width * bands

      data = Array.new(image_height) { |row| data.byteslice(row * stride, row_size) }.join if stride != row_size

      { data:, width: image_width, height: image_height, bands:, format: }
    ensure
      Pdfium.FPDFBitmap_Destroy(bitmap_ptr) if bitmap_ptr && !bitmap_ptr.null?

View on GitHub (pinned to 004a22c1c8)

Solutions

  1. Rescue per image and fall back to covering the region with an opaque drawn rect
  2. Rasterize or normalize the PDF first (ghostscript), then redact
  3. Update libpdfium; decoder coverage improves across releases
  4. Log non-decodable images for manual review in batch pipelines

Example fix

# before
page.redact(rects) { |bitmap, pr| pixel_blacken(bitmap, pr) }

# after
begin
  page.redact(rects) { |bitmap, pr| pixel_blacken(bitmap, pr) }
rescue Pdfium::PdfiumError => e
  raise unless e.message == 'Failed to get image bitmap'
  page.redact(rects) # rect-cover fallback still hides the content visually
end
Defensive patterns

Strategy: fallback

Try / catch

begin
  page.redact(rects) { |bitmap, pr| pixel_blacken(bitmap, pr) }
rescue Pdfium::PdfiumError => e
  raise unless e.message == 'Failed to get image bitmap'
  page.redact(rects) # draw-only fallback for this page
end

Prevention

When it happens

Trigger: redact with an image_processor block on pages containing JBIG2-encoded scanned documents (fax/TIFF pipelines) or JPEG2000 images; truncated image streams inside damaged PDFs.

Common situations: Redacting scanned legal or medical documents; PDFs from high-compression archival systems.

Related errors


AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21). Data as JSON: /api/errors/a525a67a88d07179. Report an issue: GitHub.