์ƒˆ์†Œ์‹

๐Ÿ’ฟ ๊ธฐํƒ€

(python) Ebook , ์ด๋ฏธ์ง€, ์Šคํฌ๋ฆฐ์ƒท์„ pdf ๋ณ€ํ™˜ ๋งคํฌ๋กœ(macro) <pyautogui , pyqt5 , pynput , pyinstaller >

  • -

* ๋„ค์ด๋ฒ„ ์†Œํ”„ํŠธ์›จ์–ด ์ž๋ฃŒ๋“ฑ๋ก(์ถ”๊ฐ€๋‚ด์šฉ)

 

https://infinitt.tistory.com/292

 

(pyinstaller , virusTotal, trojan) ํŒŒ์ด์ฌ ๋งคํฌ๋กœ ํ”„๋กœ๊ทธ๋žจ - ๋„ค์ด๋ฒ„ ์†Œํ”„ํŠธ์›จ์–ด ์ž๋ฃŒ๋“ฑ๋ก

https://infinitt.tistory.com/291 " data-og-description="* ๋ชฉ์  ์•„์ดํŒจ๋“œ๋ฅผ ์‚ฐ๊น€์— ebook์„ ๊ตฌ๋งคํ•ด๋ณด์•˜๋‹ค. ๊ต๋ณด๋ฌธ๊ณ ์—์„œ ๊ตฌ๋งคํ–ˆ๋Š”๋ฐ, ํŒŒ์ผ์„ ์ €์ž‘๊ถŒ ๋ฌธ์ œ ๋•Œ๋ฌธ์ธ์ง€ ์ž์‚ฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ๋งŒ ์—ด๋ฆฌ

infinitt.tistory.com

(๊ฒฐ๋ก ์€ ์‹คํŒจํ–ˆ๋‹ค๋Š” ๋‚ด์šฉ)

 


* ๋ชฉ์ 

์•„์ดํŒจ๋“œ๋ฅผ ์‚ฐ๊น€์— ebook์„ ๊ตฌ๋งคํ•ด๋ณด์•˜๋‹ค. ๊ต๋ณด๋ฌธ๊ณ ์—์„œ ๊ตฌ๋งคํ–ˆ๋Š”๋ฐ, ํŒŒ์ผ์„ ์ €์ž‘๊ถŒ ๋ฌธ์ œ ๋•Œ๋ฌธ์ธ์ง€ ์ž์‚ฌ์—์„œ ์ œ๊ณตํ•˜๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ๋งŒ ์—ด๋ฆฌ๊ฒŒ ํ•ด๋†“์•˜๋‹ค. ๊ทผ๋ฐ,, ๊ต๋ณดeBook ์ด๋ผ๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ณ„์  1์ ๋‹ต๊ฒŒ ํ•„๊ธฐ๊ธฐ๋Šฅ์กฐ์ฐจ ์ œ๊ณตํ•˜์ง€ ์•Š์•˜๋‹ค. ๋‚˜๋Š” ๋ฌธ์ œ์ง‘์„ ์ƒ€๋Š”๋ฐ.... ๊ทธ๋ž˜์„œ ์˜ˆ์ „๋ถ€ํ„ฐ ํ•œ๋ฒˆ ํ•ด๋ด์•ผ์ง€ ํ•ด๋ด์•ผ์ง€ ํ•˜๋˜ ํŒŒ์ด์ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งคํฌ๋กœ๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค.

 

 


 

* ํ”„๋กœ๊ทธ๋žจ ๋‹ค์šด๋กœ๋“œ

 

๋งจ ์œ„์— ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ์•Œ๊ฒ ์ง€๋งŒ ํ”„๋กœ๊ทธ๋žจ ์ธ์ฆ์„œ, ์ „์ž์„œ๋ช…์ด ์—†์–ด ์œ„ํ—˜ํ•œ ํŒŒ์ผ์ด๋ผ๊ณ  ๊ฒฝ๊ณ ์ฐฝ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. (ํ•˜์ง€๋งŒ ์•…์„ฑ์ฝ”๋“œ๋Š” ์—†๋‹ค!!)

์ž˜ ์‚ฌ์šฉํ•˜์…จ๋‹ค๋ฉด ๊นƒํ—ˆ๋ธŒ Star ํ•œ๋ฒˆ ๋ˆŒ๋Ÿฌ์ฃผ์„ธ์š”!! (์•„๋ž˜์‚ฌ์ง„ ์ฐธ๊ณ )

https://github.com/Youjunyong/ebook_to_pdf

 

GitHub - Youjunyong/ebook_to_pdf: html , js , css using local storage

html , js , css using local storage. Contribute to Youjunyong/ebook_to_pdf development by creating an account on GitHub.

github.com

 

 


*์‚ฌ์šฉํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

 

pyautogui - > ๋งคํฌ๋กœ ์ž‘๋™๋ถ€๋ถ„, ๋งˆ์šฐ์Šค์™€ ํ‚ค๋ณด๋“œ ์กฐ์ž‘ํ•ด์ค€๋‹ค.

pyqt5 -> Gui๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

pynput -> ๋งˆ์šฐ์Šค ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ†ตํ•ด, ๋งˆ์šฐ์Šค ์œ„์น˜ ์ขŒํ‘œ๊ฐ’์„ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค. 

pyinstaller -> ํŒŒ์ด์ฌ์ด ์—†๋Š” ์ปดํ“จํ„ฐ์—์„œ๋„ ์ž‘๋™ ๊ฐ€๋Šฅํ•˜๋„๋ก exeํŒŒ์ผ๋กœ ๋งŒ๋“ค์–ด ์ค€๋‹ค. (windowํ™˜๊ฒฝ์—์„œ๋งŒ ์‹คํ–‰๊ฐ€๋Šฅ)

 

 

*Pyqt5 _Gui ํ”„๋กœ๊ทธ๋žจ ๋ชจ์Šต

 

์‹คํ–‰ํŒŒ์ผ์ด๋‹ค. ์•„์ด์ฝ˜์€ power point์— ์žˆ๋Š” ์ด๋ฏธ์ง€๋กœ ๋งŒ๋“ค์—ˆ๋‹ค. 

์ƒ๊ธด๊ฑด ๋ณด์ž˜๊ฒƒ ์—†์ง€๋งŒ,, ์›ํ•˜๋Š” ๋‚ด๊ฐ€ ํ•„์š”๋กœํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํ•œ๋‹ค๋Š”๊ฒƒ์— ๋งŒ์กฑํ–ˆ๋‹ค. 

 


 

 

* ์‚ฌ์šฉ๋ฐฉ๋ฒ•

 

1. ์บก์ณํ•  ํŽ˜์ด์ง€ ์ˆ˜๋ฅผ ์ž…๋ ฅํ•œ๋‹ค.

2. ์บก์ณํ•  ์ด๋ฏธ์ง€ ์˜์—ญ์˜ ์ขŒ์ธก์ƒ๋‹จ, ๊ทธ๋ฆฌ๊ณ  ์šฐ์ธก ํ•˜๋‹จ์„ ํด๋ฆญํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์— ์ขŒํ‘œ๋ฅผ ์ž…๋ ฅํ•ด์ค€๋‹ค.

3. ๋‹ค์ŒํŽ˜์ด์ง€ ๋ฒ„ํŠผ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ž…๋ ฅํ•ด์ค€๋‹ค.

4. ํ”„๋กœ๊ทธ๋žจ์ด ๋กœ๋”ฉ์‹œ๊ฐ„๊นŒ์ง€ ๊ณ„์‚ฐํ•˜์—ฌ, ๋‹ค์ŒํŽ˜์ด์ง€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  0.8์ดˆ ํ›„์— ์„ ํƒํ•œ ์˜์—ญ์„ ์บก์ณํ•˜์—ฌ ์ˆœ์„œ๋Œ€๋กœ ์ €์žฅํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋ชฉํ‘œ ํŽ˜์ด์ง€์ˆ˜ ๋งŒํผ ์ด๊ฒƒ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

5. ์ด๋ฏธ์ง€๋Š” PNG, ๊ทธ๋ฆฌ๊ณ  ์ด๋ฆ„์€ 0.png, 1.png, 2.png, 3.png ์™€ ๊ฐ™์€ ๊ทœ์น™์œผ๋กœ ์ €์žฅ๋œ๋‹ค. ์œ—๋ถ€๋ถ„์— PDF๋งŒ๋“ค๊ธฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด ํŒŒ์ผ ๋‹ค์ด์–ด๋กœ๊ทธ๊ฐ€ ๋‚˜์˜ค๊ณ , ํŒŒ์ผ์„ ์„ ํƒํ•˜์—ฌ ๋„ฃ์–ด์ฃผ๋ฉด ํŒŒ์ผ์ด๋ฆ„ ์ˆœ์„œ๋Œ€๋กœ PDF๋กœ ํ•ฉ์ณ์ง„๋‹ค.

์ €์žฅ๋œ ์ด๋ฏธ์ง€

 

ํ•ฉ์ณ์ง„ PDF

 

์ด๋กœ์จ ํ•„๊ธฐ๊ฐ€ ์•ˆ๋˜๋Š” Ebook์— ํ•„๊ธฐ๋ฅผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

 

 

*Python code
import sys
from PyQt5.QtWidgets import QProgressBar,QMainWindow, QFileDialog,QInputDialog,  QApplication, QWidget, QPushButton, QToolTip, QAction, qApp, QFileDialog
from PyQt5.QtGui import QIcon
import pyautogui
import time
from pynput import mouse
import PyQt5
from PIL import Image

page = 0   # ์ฐ์„ ํŽ˜์ด์ง€ ์ˆ˜  
picture_size = [] #์™ผ์ชฝ ์ƒ๋‹จ ์ขŒํ‘œ , ์˜ค๋ฅธ์ชฝ ํ•˜๋‹จ ์ขŒํ‘œ

next_page = []  #๋‹ค์Œ ํŽ˜์ด์ง€์˜ ์ขŒํ‘œ
msg = "์ˆœ์„œ๋Œ€๋กœ ์ง„ํ–‰ํ•˜์„ธ์š”. ๋ฒ„ํŠผ์— ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ฆฌ๋ฉด ์„ค๋ช…์ด ๋‚˜์˜ต๋‹ˆ๋‹ค."

def get_mouse_point(x, y, button, pressed):
    if pressed and button==mouse.Button.left: 
        print('์ž…๋ ฅ๋ฐ›์€ ์ขŒํ‘œ : ', (x, y))
        picture_size.append(x)
        picture_size.append(y)
    return False

def png_to_pdf(fname):
    imglist = []
    for idx, file in enumerate(fname):
        globals()['img_{}'.format(idx)] = (Image.open(file)).convert("RGB")
        imglist.append(globals()['img_{}'.format(idx)])
    img_0.save('New_pdf.pdf',save_all=True, append_images=imglist)

def get_next_page(x, y, button, pressed):
    if pressed and button==mouse.Button.left: 
        next_page.append((x, y))
    return False
class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Ebook_To_Pdf')
        self.statusBar().showMessage(msg)
        #--------ProgressBar
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 300, 200, 40)
        self.pbar.setValue(0)
# ์•ž์˜ ๋‘ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ฐฝ์˜ x, y ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•˜๊ณ , ๋’ค์˜ ๋‘ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ฐ๊ฐ ์ฐฝ์˜ ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
        openFile = QAction('Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip("open new file")
        openFile.triggered.connect(self.show_file)

        menubar = self.menuBar()
        menubar.setNativeMenuBar(False)
        filemenu = menubar.addMenu('&โ˜…PDF๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ')
        filemenu.addAction(openFile)
        page_btn = QPushButton('1.์บก์ณํ•  ํŽ˜์ด์ง€ ์ˆ˜', self)
        page_btn.resize(page_btn.sizeHint())
        page_btn.move(30, 50)
        page_btn.clicked.connect(self.page_input)

        btn_start_point = QPushButton('2.์ขŒ์ธก ์ƒ๋‹จ ์ขŒํ‘œ ์ €์žฅ', self)
        btn_start_point.setToolTip('์ด๋ฏธ์ง€์˜ ์ขŒ์ธก ์ƒ๋‹จ ๊ผญ์ง€์ ์— ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ฆฌ๊ณ , ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.')
        btn_start_point.move(30,100)
        btn_start_point.resize(btn_start_point.sizeHint())
        btn_start_point.clicked.connect(self.Event_start_point)
        
        btn_end_point = QPushButton('3.์šฐ์ธก ํ•˜๋‹จ ์ขŒํ‘œ ์ €์žฅ', self)
        btn_end_point.setToolTip('์ด๋ฏธ์ง€ ์šฐ์ธก ํ•˜๋‹จ ๊ผญ์ง€์ ์— ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ฆฌ๊ณ , ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.')
        btn_end_point.move(30,150)
        btn_end_point.resize(btn_end_point.sizeHint())
        btn_end_point.clicked.connect(self.Event_end_point)

        btn_next_page = QPushButton('4.๋‹ค์Œ ํŽ˜์ด์ง€ ๋ฒ„ํŠผ ์ขŒํ‘œ ์ €์žฅ', self)
        btn_next_page.setToolTip('๋‹ค์Œ ์ด๋ฏธ์ง€๋กœ ๋„˜๊ธธ ๋ฒ„ํŠผ์— ๋งˆ์šฐ์Šค๋ฅผ ์˜ฌ๋ฆฌ๊ณ , ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.')
        btn_next_page.move(30,200)
        btn_next_page.resize(btn_next_page.sizeHint()) 
        btn_next_page.clicked.connect(self.Event_next_page)

        btn_run = QPushButton('5.์‹คํ–‰ํ•˜๊ธฐ', self)
        btn_run.setToolTip('ํ™”๋ฉด ๊ทธ๋Œ€๋กœ ์ฐํž™๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์ด ์ด๋ฏธ์ง€๋ฅผ ๊ฐ€๋ฆฌ์ง€ ์•Š๋„๋ก ํ•ด์ฃผ์„ธ์š”.')
        btn_run.move(30, 250)
        btn_run.resize(btn_run.sizeHint()) 
        btn_run.clicked.connect(self.get_picture)
        self.setGeometry(400,400,500,500)
        self.show()
    def page_input(self):
        global page , picture_size
        picture_size = []
        page, ok = QInputDialog.getText(self, 'Input Dialog', '์ฐ์„ ํŽ˜์ด์ง€ ์ˆ˜:')
        if ok:
            page = int(page)
            msg = "์ฐ์„ ํŽ˜์ด์ง€ ์ˆ˜ : %d, ์˜ˆ์ƒ ์†Œ์š”์‹œ๊ฐ„ : %f์ดˆ"%(page, page*0.8)
            self.status(msg)
            self.pbar.setValue(15)


    def show_file(self):
        fname = QFileDialog.getOpenFileNames(self, 'Open file' , './')
        fname[0].sort()
        if fname[0]:
            png_to_pdf(fname[0])

    def status(self,msg):
        self.statusBar().showMessage(msg)

    def Event_start_point(self):
        with mouse.Listener(on_click=get_mouse_point) as listener:
            listener.join()
            msg = "์ขŒ์ธก ์ƒ๋‹จ ์ขŒํ‘œ : (%s, %s)"%(picture_size[0],picture_size[1])
            self.status(msg)
            self.pbar.setValue(30)

    def Event_end_point(self):
        with mouse.Listener(on_click=get_mouse_point) as listener:
            listener.join()
            msg = "์šฐ์ธก ํ•˜๋‹จ ์ขŒํ‘œ : (%s, %s)"%(picture_size[0],picture_size[1])
            self.status(msg)
            self.pbar.setValue(45)
    def Event_next_page(self):
        with mouse.Listener(on_click=get_next_page) as listener:
            listener.join()
            msg = "'๋‹ค์ŒํŽ˜์ด์ง€'๋ฒ„ํŠผ ์ขŒํ‘œ : %s"%next_page
            self.status(msg)
            self.pbar.setValue(60)
    def get_picture(self):
        rest_of_percent = 40//page
        for i in range(page):
            if len(picture_size) >= 4:
                pyautogui.screenshot("%s.png" % i, region=(picture_size[0], picture_size[1],
                picture_size[2]-picture_size[0],picture_size[3]-picture_size[1]))
            pyautogui.click(*next_page)
            rest_of_percent += 40//page
            self.pbar.setValue(60+rest_of_percent)
            time.sleep(0.8)
        self.pbar.setValue(100)
        msg = "์ด๋ฏธ์ง€ ์บก์ณ ์™„๋ฃŒ. PDF๋ฉ”๋‰ด๋ฅผ ๋ˆŒ๋Ÿฌ PDF๋กœ ๋ณ€ํ™˜ํ•˜์„ธ์š”!"
        self.status(msg)
if __name__ == '__main__':
   app = QApplication(sys.argv)
   ex = MyApp()
   sys.exit(app.exec_())

 

 

 

๋ถˆ๋ฒ• ์šฉ๋„๋กœ๋Š” ์‚ฌ์šฉํ•˜์ง€ ๋ง์•„์ฃผ์‹œ๊ธธ...

+ ๋งŒ๋“ ์ง€ ์˜ค๋ž˜๋œ ํ”„๋กœ๊ทธ๋žจ์ž…๋‹ˆ๋‹ค.  ์ฝ”๋“œ ๊ฐœ์„ ์‚ฌํ•ญ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“  PullRequestํ•ด์ฃผ์„ธ์š” ใ…Žใ…Ž

Contents

ํฌ์ŠคํŒ… ์ฃผ์†Œ๋ฅผ ๋ณต์‚ฌํ–ˆ์Šต๋‹ˆ๋‹ค

์ด ๊ธ€์ด ๋„์›€์ด ๋˜์—ˆ๋‹ค๋ฉด ๊ณต๊ฐ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.