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

weasyprint generates blurry/opaque image #2131

Closed
jelleheijne-nps opened this issue Apr 22, 2024 · 14 comments
Closed

weasyprint generates blurry/opaque image #2131

jelleheijne-nps opened this issue Apr 22, 2024 · 14 comments
Labels
bug Existing features not working as expected
Milestone

Comments

@jelleheijne-nps
Copy link

jelleheijne-nps commented Apr 22, 2024

I am using the weasyprint library to export a pdf based on html and css code. However, it generates very inconsistent images. Sometimes the images look like they are opaque. In this code I generate an image of a histogram twice, where the first image looks opaque and the second looks normal. As you can see on the image below.

weasyprint image

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    {% load static %}
    <link href="{% static 'livedata/css/main.css' %}" rel="stylesheet"/>
    <meta charset="UTF-8">
    <title>PDF Preview</title>
</head>
<body>
<div><h1>Summary report {{scout.name}}</h1>
    <h6 style="color: rgba(0, 0, 0, 0.5); font-size: 20px;">15-04-2024 11:54:20 - 15-05-2024
        11:54:20</h6>
</div>

<h2 style="color: rgba(0, 0, 0, 0.7); margin-bottom: 1em;">Engine speed and load over time</h2>
<img src="{% static 'livedata/plots/'%}plot.jpg" alt="..." width="700" height="400">

<div style="height: 100px;"></div>
<h2 style="color: rgba(0, 0, 0, 0.7); margin-bottom: 1em;">Engine speed</h2>

<div>
    <div class="row">
        <div class="report-card" style="width: 160px; height: 160px; margin-right: 16px;">
            <p class="report-description">Minimum</p>
            <p class="report-value">1492</p>
            <p class="report-description">RPM</p>
        </div>
        <div class="report-card" style="width: 160px; height: 160px; margin-left: 16px; margin-right: 16px;">
            <p class="report-description">Maximum</p>
            <p class="report-value">1503</p>
            <p class="report-description">RPM</p>
        </div>
        <div class="report-card" style="width: 160px; height: 160px; margin-left: 16px;">
            <p class="report-description">Average</p>
            <p class="report-value">1500</p>
            <p class="report-description">RPM</p>
        </div>
    </div>
    <img src="{% static 'livedata/plots/'%}speed_histogram.jpg" alt="..." width="480" height="524">
</div>

<img src="{% static 'livedata/plots/'%}speed_histogram.jpg" alt="..." width="480" height="524">
</body>
</html>

CSS:

.report-card {
    background-color: white;
    border-radius: 20px;
    border: 3px solid #EDEFEC;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
}

.report-card > .row,
.report-card .col {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    margin: 0; /* Override any default Bootstrap margins */
}

.report-card .col {
    flex-direction: column;
}

.report-value,
.report-description {
    width: 100%; /* Ensures text elements fill the flex container */
    text-align: center; /* Center text horizontally */
    margin: 0; /* Remove any default margins that might cause misalignment */
}

.report-value {
    font-size: 32px;
    font-weight: bold;
    margin-top: 8px;
    line-height: 0.8;
    padding: 0;
}

.report-description {
    font-size: 16px;
    color: rgba(0, 0, 0, 0.5);
    width: 100%; /* Ensures text elements fill the flex container */
    text-align: center; /* Center text horizontally */
    margin: 0; /* Remove any default margins that might cause misalignment */
    white-space: nowrap; /* Prevents the text from wrapping */
}

.row {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
}

.col-8, .col-4 {
    flex: 0 0 auto; /* Prevent flex items from growing or shrinking */
}

.col-8 {
    width: 66.66%; /* Approximate division of 8/12 of the row */
}

.col-4 {
    width: 33.33%; /* Approximate division of 4/12 of the row */
}

.col-9 {
    width: 75%; /* Approximate division of 9/12 of the row */
}

.col-3 {
    width: 25%; /* Approximate division of 3/12 of the row */
}

#speed-load-chart {
    width: 100%; /* Full width of the report card */
    flex-grow: 1; /* Allow the chart to fill available space */
}
@liZe
Copy link
Member

liZe commented Apr 22, 2024

Hi,

Could you please share your image and your PDF?

@jelleheijne-nps
Copy link
Author

Hi,

Could you please share your image and your PDF?

speed_histogram
report - 2024-04-22T115549.705.pdf

@liZe
Copy link
Member

liZe commented Apr 22, 2024

There’s no problem when I try to reproduce with your code:

graph.pdf

Could you generate a real HTML file instead of sharing the template? Maybe there’s something wrong in the generated HTML.

The best solution if you want us to reproduce your problem is to produce static HTML and CSS files, and share an archive containing everything (including images) to generate the exact same PDF you’re generating.

@jelleheijne-nps
Copy link
Author

Thanks for your response. I included all the files:
plot
speed_histogram

This is my static html:

<!DOCTYPE html>
<html lang="en">
<head>
    
    <link href="/static/livedata/css/main.css" rel="stylesheet"/>
    <meta charset="UTF-8">
    <title>PDF Preview</title>
</head>
<body>
<div><h1>Summary report Scout bij Benschop</h1>
    <h6 style="color: rgba(0, 0, 0, 0.5); font-size: 20px;">15-04-2024 11:54:20 - 15-05-2024
        11:54:20</h6>
</div>

<h2 style="color: rgba(0, 0, 0, 0.7); margin-bottom: 1em;">Engine speed and load over time</h2>
<img src="/static/livedata/plots/plot.jpg" alt="..." width="700" height="400">

<div style="height: 100px;"></div>
<h2 style="color: rgba(0, 0, 0, 0.7); margin-bottom: 1em;">Engine speed</h2>

<div>
    <div class="row">
        <div class="report-card" style="width: 160px; height: 160px; margin-right: 16px;">
            <p class="report-description">Minimum</p>
            <p class="report-value">1492</p>
            <p class="report-description">RPM</p>
        </div>
        <div class="report-card" style="width: 160px; height: 160px; margin-left: 16px; margin-right: 16px;">
            <p class="report-description">Maximum</p>
            <p class="report-value">1503</p>
            <p class="report-description">RPM</p>
        </div>
        <div class="report-card" style="width: 160px; height: 160px; margin-left: 16px;">
            <p class="report-description">Average</p>
            <p class="report-value">1500</p>
            <p class="report-description">RPM</p>
        </div>
    </div>
    <img src="/static/livedata/plots/speed_histogram.jpg" alt="..." width="480" height="524">
</div>

<img src="/static/livedata/plots/speed_histogram.jpg" alt="..." width="480" height="524">
</body>
</html>

@liZe
Copy link
Member

liZe commented Apr 23, 2024

I don’t have the problem when using your files.

graph.pdf

Do you have the problem with these exact files?

@jelleheijne-nps
Copy link
Author

Yes with these exact files. This is how I generate the pdf:

# Render the HTML template to a string
    html_string = render_to_string('livedata/report.html', context, request)

    # Create a FontConfiguration instance
    font_config = FontConfiguration()

    # Find the absolute filesystem path to the font
    regular_font_path = finders.find('livedata/fonts/Inter-Regular.ttf')
    regular_font_path = 'file:///' + regular_font_path.replace('\\', '/')  # Replace backslashes with forward slashes

    bold_font_path = finders.find('livedata/fonts/Inter-Bold.ttf')
    bold_font_path = 'file:///' + bold_font_path.replace('\\', '/')  # Replace backslashes with forward slashes

    # Set up CSS with both font variants
    font_config = FontConfiguration()
    css = CSS(string=f'''
        @font-face {{
            font-family: 'Inter';
            src: url('{regular_font_path}') format('truetype');
            font-weight: normal;
        }}
        @font-face {{
            font-family: 'Inter';
            src: url('{bold_font_path}') format('truetype');
            font-weight: bold;
        }}
        body, h1 {{
            font-family: 'Inter', sans-serif;
        }}
        strong, b {{
            font-family: 'Inter';
            font-weight: bold;
        }}
    ''', font_config=font_config)

    # Create a WeasyPrint HTML object with the font configuration
    html = HTML(string=html_string, base_url=request.build_absolute_uri())
    result = html.write_pdf(stylesheets=[css], font_config=font_config)  # Apply the CSS here

    # Create an HTTP response with the PDF as attachment
    response = HttpResponse(result, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="report.pdf"'

    # Configure logging to show messages from WeasyPrint
    logging.basicConfig(level=logging.DEBUG)

    return response

@jelleheijne-nps
Copy link
Author

I don’t have the problem when using your files.

graph.pdf

Do you have the problem with these exact files?

I think it only happens when the graph is on the same page as the cards, like in my pdf. In yours it is on a new page, because your font is a bit smaller. If you increase the height of the div above the cards, they should be on the same page.

@liZe
Copy link
Member

liZe commented Apr 23, 2024

I’m sorry, but please provide an archive with code that’s 100% ready to use, so that we can easily reproduce. 🙏🏽

@jelleheijne-nps
Copy link
Author

graph_pdf.zip

Everything should be in here

@liZe
Copy link
Member

liZe commented Apr 23, 2024

Thank you.

Here’s a minimal sample to reproduce:

<img src="plots/plot.jpg">
<p style="color: #0001">text</p>

@liZe liZe closed this as completed in 3809836 Apr 23, 2024
@liZe
Copy link
Member

liZe commented Apr 23, 2024

It’s now fixed and tested, feedback is welcome!

@liZe liZe added the bug Existing features not working as expected label Apr 23, 2024
@liZe liZe added this to the 62.0 milestone Apr 23, 2024
@jelleheijne-nps
Copy link
Author

I don't see any difference. Do I need to reinstall the package to get the fixed version?

@liZe
Copy link
Member

liZe commented Apr 25, 2024

I don't see any difference. Do I need to reinstall the package to get the fixed version?

It’s fixed in the main branch, not in the latest release.

You can install the current main branch (not in production!) with pip install --force git+https://github.com/Kozea/WeasyPrint.

@jelleheijne-nps
Copy link
Author

It works. Thank you!

okkays pushed a commit to okkays/WeasyPrint that referenced this issue May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Existing features not working as expected
Projects
None yet
Development

No branches or pull requests

2 participants