diff --git a/src/pypdfium2/_helpers/_utils.py b/src/pypdfium2/_helpers/_utils.py index 72123c6ba..56da3282b 100644 --- a/src/pypdfium2/_helpers/_utils.py +++ b/src/pypdfium2/_helpers/_utils.py @@ -4,9 +4,9 @@ import pypdfium2._pypdfium as pdfium -def colour_tohex(r, g, b, a=255): +def colour_tohex(r, g, b, a=255, greyscale=False): """ - Convert an RGBA colour specified by four integers ranging from 0 to 255 to a single ARGB32 value. + Convert an RGBA colour specified by four integers ranging from 0 to 255 to a single value. Returns: (int, bool): The colour value, and a boolean signifying if an alpha channel is needed. @@ -16,7 +16,10 @@ def colour_tohex(r, g, b, a=255): if a == 255: use_alpha = False - colours = (a, r, g, b) + if greyscale and not use_alpha: + colours = (a, r, g, b) + else: + colours = (a, b, g, r) for col in colours: assert 0 <= col <= 255 diff --git a/src/pypdfium2/_helpers/page.py b/src/pypdfium2/_helpers/page.py index ae7d0e569..b56f3c377 100644 --- a/src/pypdfium2/_helpers/page.py +++ b/src/pypdfium2/_helpers/page.py @@ -304,7 +304,7 @@ def render_base( if colour is None: fpdf_colour, use_alpha = None, True else: - fpdf_colour, use_alpha = colour_tohex(*colour) + fpdf_colour, use_alpha = colour_tohex(*colour, greyscale=greyscale) cl_format, cl_pdfium = get_colourformat(use_alpha, greyscale) n_colours = len(cl_format) @@ -328,6 +328,8 @@ def render_base( pdfium.FPDFBitmap_FillRect(bitmap, 0, 0, width, height, fpdf_colour) render_flags = 0 + if cl_pdfium != pdfium.FPDFBitmap_Gray: + render_flags |= pdfium.FPDF_REVERSE_BYTE_ORDER if annotations: render_flags |= pdfium.FPDF_ANNOT if greyscale: @@ -352,7 +354,7 @@ def render_base( pdfium.FPDFDOC_ExitFormFillEnvironment(form_fill) - return data_holder, cl_format, (width, height) + return data_holder, ColourMapping[cl_format], (width, height) def render_tobytes(self, *args, **kwargs): @@ -384,7 +386,7 @@ def render_topil(self, *args, **kwargs): raise RuntimeError("Pillow library needs to be installed for render_topil().") data_holder, cl_format, size = self.render_base(*args, **kwargs) - pil_image = PIL.Image.frombytes(ColourMapping[cl_format], size, data_holder.get_data(), "raw", cl_format, 0, 1) + pil_image = PIL.Image.frombytes(cl_format, size, data_holder.get_data(), "raw", cl_format, 0, 1) data_holder.close() return pil_image diff --git a/tests/helpers/test_renderer.py b/tests/helpers/test_renderer.py index 9d92178f4..60bf3769e 100644 --- a/tests/helpers/test_renderer.py +++ b/tests/helpers/test_renderer.py @@ -129,19 +129,20 @@ def test_render_page_greyscale(sample_page): @pytest.mark.parametrize( - "colour", + ["name", "colour"], [ - (255, 255, 255, 255), - (60, 70, 80, 100), - (255, 255, 255), - (0, 255, 255), - (255, 0, 255), - (255, 255, 0 ), + ("1", (255, 255, 255, 255)), + ("2", (60, 70, 80, 100)), + ("3", (255, 255, 255)), + ("4", (0, 255, 255)), + ("5", (255, 0, 255)), + ("6", (255, 255, 0 )), ] ) -def test_render_page_bgcolour(colour, sample_page): +def test_render_page_bgcolour(name, colour, sample_page): pil_image = sample_page.render_topil(colour=colour, scale=0.5) + pil_image.save( join(OutputDir, "bgcolour_%s.png" % name) ) assert pil_image.size == (298, 421) px_colour = colour @@ -160,14 +161,15 @@ def test_render_page_tobytes(sample_page): bytedata, cl_format, size = sample_page.render_tobytes(scale=0.5) assert isinstance(bytedata, bytes) - assert cl_format == "BGR" + assert cl_format == "RGB" assert size == (298, 421) assert len(bytedata) == size[0] * size[1] * len(cl_format) - pil_image = PIL.Image.frombytes("RGB", size, bytedata, "raw", "BGR") + pil_image = PIL.Image.frombytes("RGB", size, bytedata, "raw", cl_format) assert pil_image.mode == "RGB" assert pil_image.size == (298, 421) assert isinstance(pil_image, PIL.Image.Image) + pil_image.save( join(OutputDir, "render_bytes.jpg") ) pil_image.close()