File size: 3,014 Bytes
4c85f97
611be2f
4c85f97
 
 
21bc43d
4c85f97
679df68
72673b1
4c85f97
 
72673b1
4c85f97
 
39ae163
 
4c85f97
 
 
39ae163
 
 
 
611be2f
39ae163
 
 
 
 
 
 
21bc43d
4c85f97
 
 
611be2f
52f175a
679df68
 
52f175a
 
611be2f
21bc43d
 
87d950a
 
21bc43d
87d950a
 
 
 
21bc43d
 
4c85f97
 
679df68
 
 
bc4b939
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
679df68
bc4b939
 
 
 
 
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
import gradio as gr
import pikepdf
import requests
import io
import tempfile
import os

def compress_pdf(input_file, url):
    if input_file is None and (url is None or url.strip() == ""):
        return None, "Please provide either a file or a URL."
    
    if input_file is not None and url and url.strip() != "":
        return None, "Please provide either a file or a URL, not both."
    
    try:
        if url and url.strip() != "":
            response = requests.get(url)
            response.raise_for_status()
            pdf_content = io.BytesIO(response.content)
            initial_size = len(response.content)
        else:
            if hasattr(input_file, 'name'):
                # If input_file is a file path
                pdf_content = input_file.name
                initial_size = os.path.getsize(input_file.name)
            else:
                # If input_file is file-like object
                pdf_content = io.BytesIO(input_file.read())
                pdf_content.seek(0, io.SEEK_END)
                initial_size = pdf_content.tell()
                pdf_content.seek(0)

        with tempfile.NamedTemporaryFile(delete=False, suffix=".pdf") as temp_file:
            temp_file_path = temp_file.name

        pdf = pikepdf.Pdf.open(pdf_content)
        
        # Always use the highest compression setting
        compression_params = dict(compress_streams=True, object_stream_mode=pikepdf.ObjectStreamMode.generate)

        pdf.save(temp_file_path, **compression_params)

        # Check the compression ratio achieved
        compressed_size = os.path.getsize(temp_file_path)
        compression_ratio = compressed_size / initial_size
        compression_percentage = (1 - compression_ratio) * 100

        # If compression increased file size or didn't meet minimum threshold, return original file
        if compression_ratio >= 1 or compression_percentage < 5:
            os.remove(temp_file_path)
            return input_file, f"Unable to compress the PDF effectively. Original file returned. (Attempted compression: {compression_percentage:.2f}%)"

        return temp_file_path, f"PDF compressed successfully! Compression achieved: {compression_percentage:.2f}%"
    except Exception as e:
        return None, f"Error compressing PDF: {str(e)}"

def process_and_compress(input_file, url):
    output_file, message = compress_pdf(input_file, url)
    if output_file:
        return output_file, message
    else:
        return None, message

with gr.Blocks() as demo:
    gr.Markdown("# PDF Compressor")
    with gr.Row():
        input_file = gr.File(label="Upload PDF")
        url_input = gr.Textbox(label="Or enter PDF URL")
    compress_btn = gr.Button("Compress")
    output_file = gr.File(label="Download Compressed PDF")
    message = gr.Textbox(label="Message")

    compress_btn.click(
        process_and_compress,
        inputs=[input_file, url_input],
        outputs=[output_file, message]
    )

if __name__ == "__main__":
    demo.launch(share=True)