File size: 5,364 Bytes
78a50b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import os
from pyppeteer import launch
from PIL import Image
import json
import random
from pydantic import BaseModel
from fastapi import FastAPI
from jinja2 import Environment, FileSystemLoader

app = FastAPI()

class HtmlInput(BaseModel):
    message: str



async def convert_html_to_image(html, output_file, width=612, height=800, device_scale_factor=2):
    browser = await launch()
    page = await browser.newPage()
    await page.setViewport({'width': width, 'height': height, 'deviceScaleFactor': device_scale_factor})
    await page.setContent(html)
    # Capture only the viewport without extra white space
    await page.screenshot({'path': output_file})
    await browser.close()
    return output_file  # Return the path of the captured image

# Function to tilt the content randomly
def tilt_content(html_content):
    tilt_angle = random.randint(-3, 2)  # Adjust the range of tilting angle as needed
    tilted_content = f'<div style="transform: rotate({tilt_angle}deg);">{html_content}</div>'
    return tilted_content

def apply_random_css(html_content):
    selected_css = random.choice([".txORqLQ { font-size: 13px; font-weight: bold; fill: #000080; color:#000080; }",
                                  ".txORqLQ { font-size: 12px; font-weight: bold; fill: #000080; color:#000080; }",
                                  ".txORqLQ { font: bold 10px 'Courier New',Courier,monospace; }",
                                  ".txORqLQ { font: bold 10.5px 'Courier New',Courier,monospace; }"])
    offset_content=html_content
    offset_content = f'<style>{selected_css}</style>' + offset_content
    return offset_content

def apply_random_css_positioning(html_content):
    selected_css = random.choice([".address { position: relative;bottom: 48.6rem;left: 16.8rem;width: 11rem; margin-top:0.3rem}",
                                  ".address { position: relative;bottom: 47.8rem;left: 10.9rem;width: 30rem; margin-top:0.3rem}"
                                  ])
    offset_content=html_content
    offset_content = f'<style>{selected_css}</style>' + offset_content
    return offset_content

def apply_position_offset(html_content):
    # Random offsets in x and y directions
    offset_x = random.randint(-20, 20)  # Adjust the range of x offset as needed
    offset_y = random.randint(-20, 20)  # Adjust the range of y offset as needed
    
    # Apply the offsets to the content
    offset_content = f'<div style="position: relative; left: {offset_x}px; top: {offset_y}px;">{html_content}</div>'
    return offset_content

async def optimize_image(input_file, output_file, target_size_kb=200):
    # Open the image using PIL
    with Image.open(input_file) as img:
        # Calculate the initial quality to achieve the target size
        quality = 95
        temp_output_file = output_file + ".temp.jpg"
        img.save(temp_output_file, format='JPEG', quality=quality, optimize=True)
        while os.path.getsize(temp_output_file) > target_size_kb * 1024 and quality > 0:
            # Reduce the quality and save to temporary file
            quality -= 5
            img.save(temp_output_file, format='JPEG', quality=quality, optimize=True)
        
        # Save the optimized image to the output file
        os.replace(temp_output_file, output_file)

async def mainFunction(html_content:str):
    # Create img folder if not exists
    if not os.path.exists('img'):
        os.makedirs('img')
    if not os.path.exists('json'):
        os.makedirs('json')

    filename = 'sample.html'

    # Write the HTML string to the file
    with open(filename, 'w',encoding='utf-8') as file:
        file.write(html_content)

    template_loader = FileSystemLoader(searchpath=".")
    template_env = Environment(loader=template_loader)
    template = template_env.get_template(filename)

    # Load JSON data from files
    with open("modified_data.json", "r", encoding="utf-8") as universal_file:
        universal_json_data = json.load(universal_file)
    

    # Define the start number
    start_number = 17800

    # Loop over each record in the universal JSON
    for index, record in enumerate(universal_json_data):
        # Increment index by start_number
        index += start_number
        
        # Generate json file

        # Load the template

        json_output_file = os.path.join('json', f"{index:05d}.json")
        with open(json_output_file, "w", encoding="utf-8") as json_file:
            json.dump(record, json_file, indent=4, ensure_ascii=False)
        html_output = template.render(record)
        html_output= apply_random_css(html_output)
        html_output=apply_random_css_positioning(html_output)


        # Apply random position offset
        # html_output = apply_position_offset(html_output)

        # Tilt the content randomly
        # html_output = tilt_content(html_output)

               
        # Convert HTML to image
        output_image_file = os.path.join('img', f"{index:05d}.jpg")
        captured_image_path = await convert_html_to_image(html_output, output_image_file)
        
        # Optimize the image to be less than 200KB
        await optimize_image(captured_image_path, output_image_file)

# Run the asynchronous main function
@app.post("/convert-html-to-image/")
async def convert_html_to_image_endpoint(html_content:HtmlInput):
    await mainFunction(html_content.message)