File size: 4,707 Bytes
18f2633
 
 
 
d580476
18f2633
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
041ed15
 
18f2633
 
 
 
041ed15
18f2633
 
 
 
041ed15
18f2633
041ed15
18f2633
 
 
 
 
d580476
 
18f2633
d580476
 
18f2633
d580476
 
 
 
 
 
 
 
 
 
 
18f2633
 
d580476
18f2633
 
 
 
419b027
18f2633
 
 
 
 
 
 
 
 
041ed15
 
 
d580476
 
21835d3
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
import streamlit as st
from PIL import Image, ImageFilter, ImageOps
import sys
import io
from utils import download_file, remove_file
import fitz #pip install PyMuPDF

def add_border(image, border):
    img_with_border = ImageOps.expand(image, border=border, fill="black")
    return img_with_border

def add_shadow(image, offset, shadow, border):
    total_width = image.size[0] + abs(offset[0]) + 2 * border
    total_height = image.size[1] + abs(offset[1]) + 2 * border
    back = Image.new("RGBA", (total_width, total_height), (0, 0, 0, 0))
    shadow = Image.new("RGBA", (image.size[0], image.size[1]), (0, 0, 0, 255))
    shadow_left = border + max(offset[0], 0)
    shadow_top = border + max(offset[1], 0)
    back.alpha_composite(shadow, (shadow_left, shadow_top))
    back = back.filter(ImageFilter.GaussianBlur(10))
    back.convert("RGBA") 
    img_left = border - min(offset[0], 0)
    img_top = border - min(offset[1], 0)
    back.paste(image, (img_left, img_top), image.convert("RGBA"))
    back.convert("RGBA")
    return back

def stack(images, mode):
    num_images = len(images)
    widths, heights = zip(*(i.size for i in images))
    if mode == "Unroll":
        separation = 700
        total_width = sum(widths) - separation * (num_images - 1)
        max_height = max(heights)
        new_im = Image.new("RGBA", (total_width, max_height))
        x_offset = total_width - images[0].size[0]
        for im in images:
            new_im.alpha_composite(im, (x_offset, 0))
            x_offset -= im.size[0] - separation
    elif mode == "Stack":
        separation = 10
        total_width = widths[0] + separation * (num_images - 1)
        total_height = heights[0] + separation * (num_images - 1)
        new_im = Image.new("RGBA", (total_width, total_height))
        x_offset = total_width - images[0].size[0]
        y_offset = 0
        for im in images:
            new_im.alpha_composite(im, (x_offset, y_offset))
            x_offset -= separation
            y_offset += separation
    elif mode == "Cover":
        new_im = images[-1]
    return new_im

st.set_page_config(page_title="pdf2preview", page_icon="📄", layout="centered", initial_sidebar_state="collapsed", menu_items=None)
hide_streamlit_style = """
	<style>
	MainMenu {visibility: hidden;}
	footer {visibility: hidden;}
	* {font-family: Avenir;}
    h1 {text-align: center;}
	.css-gma2qf {display: flex; justify-content: center; font-size: 36px; font-weight: bold;}
	a:link {text-decoration: none;}
	a:hover {text-decoration: none;}
	.st-ba {font-family: Avenir;}
    .st-button {text-align: center;}
	</style>
	"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
st.title("PDF ➡️ Preview")
st.markdown("Generate a preview image for your PDF file.")

col1, col2 = st.columns([1, 5])
with col1:
    st.radio("Pick a layout", ("Unroll", "Stack", "Cover"), key="mode")
with col2:
    st.image("example.png")
st.file_uploader("Upload your PDF", type="pdf", key="file")
st.write("or")
url = st.text_input("Submit link to PDF")


if st.button('Generate preview'):
    with st.spinner("Processing..."):
        if st.session_state.file is not None:
            file = fitz.open("pdf", st.session_state.file.read())
        else:
            try:
                filename = download_file(url)
                file = fitz.open(filename)
            except:
                e = ValueError('Could not download pdf file from URL')
                st.error('Please enter a valid pdf URL', icon="🚨")
                raise e

        zoom = 2
        mat = fitz.Matrix(zoom, zoom)
        num_pages = file.page_count
        imgs = []
        for page_num in range(num_pages):
            page = file.load_page(page_num)
            pix = page.get_pixmap(matrix = mat)
            data = pix.tobytes("png")
            img = Image.open(io.BytesIO(data))
            img_with_border = add_border(img, border=1)
            img_with_shadow = add_shadow(img_with_border, offset=(0,0), shadow=(0,0,0,255), border=20)
            imgs.append(img_with_shadow)
        preview = stack(imgs[::-1], st.session_state.mode)
        st.image(preview)
        output = io.BytesIO()
        preview.save(output, format="PNG")
        output = output.getvalue()
        b1, b2, b3 = st.columns([1, 1, 1])
        with b2:
            download = st.download_button(label="Download image", data=output, file_name="pdf2preview.png", mime="image/png")
        if st.session_state.file is None:
            remove_file(filename)
st.markdown("By [David Chuan-En Lin](https://chuanenlin.com). PDF URL support by [Eliott Zemour](https://github.com/EliottZemour). Play with the code at https://github.com/chuanenlin/pdf2preview.")