Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stamp font and position is inverted for some PDFs. #312

Open
aaabhilash97 opened this issue Aug 29, 2023 · 5 comments
Open

stamp font and position is inverted for some PDFs. #312

aaabhilash97 opened this issue Aug 29, 2023 · 5 comments
Labels
enhancement New feature or request

Comments

@aaabhilash97
Copy link

The stamp font and box position are vertically inverted from what is expected. This issue only occurs in PDFs that are converted from HTML. For other PDFs, the font and position are in the expected manner.

Code sample to reproduce the issue.

import concurrent.futures

import asyncio
from loguru import logger
# import aiofiles
from pyhanko import stamp
from pyhanko.pdf_utils import text, images
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import fields, signers
import secrets
import string




async def stamp2():
    with open("./input2.pdf", "rb") as fin:
        pdf_out = IncrementalPdfFileWriter(fin, strict=False)
        stamper = stamp.TextStamp(
            writer=pdf_out,
            style=stamp.TextStampStyle(
                stamp_text="Digitally signed by: %(signer)s\nTime: %(ts)s\nDevice ip: 129.001.11.1\nDevice os: Android\nBorrower name:Abhilash km",
                text_box_style=text.TextBoxStyle(
                    font_size=10,
                ),
                background=images.PdfImage("logo.png"),
                
            ),
            text_params={"signer": "OKOK"},
            # box=(200, 600, 400, 660),
        )
        stamper.apply(0, 200, 1)
        
        with open("./output2.pdf", "wb") as out:
            pdf_out.write(out)

Expected behaviour is stamp affixed bottom of page.

Issue screenshot: (HTML converted pdf)(issue happening in wkhtmltopdf pdf, pdf created from chrome)
Screenshot 2023-08-29 at 9 41 03 AM

Tried python 3.11.4 macOS and Linux

Working as expected in other pdf:
Screenshot 2023-08-29 at 9 43 43 AM

@MatthiasValvekens Do you have any idea why this is happening?

@MatthiasValvekens
Copy link
Owner

Is the "bad" PDF rotated? If so, it's a known issue; see discussion and links in #265.

There's an open PR purporting to fix the problem, but it needs a bit of work...

@aaabhilash97
Copy link
Author

@MatthiasValvekens probably this might be the issue. Will explore this.

In my case visible signature working fine(visible_sig_settings=fields.VisibleSigSettings(rotate_with_page=True)).

When I'm trying to put stamp alone issue is happening.
Couldn't able to find this rotate_with_page option in stamp functions.

@aaabhilash97
Copy link
Author

Hi @MatthiasValvekens
Anyway we can specify rotate with page option in stamp function. Or does that require changes in module?

@MatthiasValvekens
Copy link
Owner

The rotate_with_page option in signatures works by setting an annotation flag; that's not possible in this case because the stamp function (when used in the most straightforward way) directly acts on page content.

There are obviously ways to fix this ad-hoc without making too many code changes, but they all require some knowledge about the PDF graphics model... :/ The approach proposed in #266 can be made to cover your use case, but not in the way it's implemented there.

I'm currently very strapped for time, but I'll flag this as a feature request to be completed together with the fix for #265.

@MatthiasValvekens MatthiasValvekens added the enhancement New feature or request label Aug 29, 2023
@aaabhilash97
Copy link
Author

aaabhilash97 commented Sep 2, 2023

We can fix the rotation issue of a PDF using the transfer_rotation_to_content() option in https://pypdf.readthedocs.io/en/3.15.4/user/add-watermark.html.

https://pypdf.readthedocs.io/en/3.15.4/modules/PageObject.html?highlight=transfer_rotation_to_content#pypdf._page.PageObject.transfer_rotation_to_content

I am adding it here because it may be helpful to someone looking for a solution.

import io
from io import BytesIO

from loguru import logger
from pyhanko import stamp
from pyhanko.pdf_utils import images, text
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import signers
from pypdf import PdfReader, PdfWriter

cms_signer = signers.SimpleSigner.load(
    "./key.pem",
    "./cert.pem",
)

async def all_page_stamp_single_sign(
    inf: bytes,
    stamp_text: str,
):
    rotation_fixer = PdfWriter(clone_from=PdfReader(BytesIO(inf)))
    for page in rotation_fixer.pages:
        page.transfer_rotation_to_content()
        page.compress_content_streams(level=9)

    rotation_fixed_pdf_out = io.BytesIO()
    rotation_fixer.write(rotation_fixed_pdf_out)
    stamp_pdf_writer = IncrementalPdfFileWriter(rotation_fixed_pdf_out, strict=False)
    stamper = stamp.TextStamp(
        writer=stamp_pdf_writer,
        style=stamp.TextStampStyle(
            stamp_text=stamp_text,
            text_box_style=text.TextBoxStyle(
                font_size=7,
            ),
            background=images.PdfImage("logo.png"),
        ),
    )
    try:
        for i in range(40):
            stamper.apply(i, 180, 1)
    except Exception as e:
        logger.debug("Stamp apply exception", exception=e)

    stamped_pdf_out = io.BytesIO()
    stamp_pdf_writer.write(stamped_pdf_out)
    signed_pdf_writer = IncrementalPdfFileWriter(stamped_pdf_out, strict=False)
    return await signers.async_sign_pdf(
        signed_pdf_writer,
        signers.PdfSignatureMetadata(field_name="Signature"),
        signer=cms_signer,
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants