글 작성자: HEROHJK

저번 포스트에 이어서 마저 작성합니다.


저번에 이미지를 PDF로 바꿔봤는데요, 오늘은 그 이미지 PDF를 페이지PDF에 합성하는 부분을 처리 해 보겠습니다.


다음은 샘플 pdf파일과 최종 완성 비교 사진입니다.


testpage.pdf



이제 시작 해 보겠습니다.


다음과같이 PyPDF2 라이브러리를 설치 해 줍니다

(유명한 PDF 편집 라이브러리입니다)


pip install pypdf2


PDF를 합성하는건 비교적 쉽습니다.


코드를 보시죠.


from PyPDF2 import PdfFileReader, PdfFileWriter

def PDFMerge(savePath, pdfPath, watermarkPdfPath):
    # pdf파일 불러오기
    pdfFile = open(pdfPath,'rb')
    pdfReader = PdfFileReader(pdfFile, strict=False)

    # 워터마크 PDF파일 불러오기
    watermarkPdfFile = open(watermarkPdfPath, 'rb')
    watermarkPdf = PdfFileReader(watermarkPdfFile, strict=False).getPage(0)

    pdfWriter = PdfFileWriter()

    #PDF 페이지 수만큼 반복
    for pageNum in range(pdfReader.numPages):

        #페이지를 불러온다
        pageObj = pdfReader.getPage(pageNum)

        #중앙으로 놓기 위해 좌표를 구한다
        x = (pageObj.mediaBox[2] - watermarkPdf.mediaBox[2]) / 2
        y = (pageObj.mediaBox[3] - watermarkPdf.mediaBox[3]) / 2

        # 워터마크페이지와 합친다
        pageObj.mergeTranslatedPage(page2=watermarkPdf, tx=x, ty=y, expand=False)

        #합친걸 저장할 PDF파일에 추가한다
        pdfWriter.addPage(pageObj)

    #저장
    resultFile = open(savePath, 'wb')
    pdfWriter.write(resultFile)


간단합니다. pdf파일과 워터마크를 불러오고, 빈 PDF파일을 생성합니다.


두 PDF를 합쳐서 빈 PDF파일에 집어넣습니다.


이 행동을 PDF파일 페이지 수 만큼 반복합니다.


그리고 저장하면 끝입니다.


조금 궁금하실만한점을 생각 해 보자면, mediaBox에서 2와 3인데요, 저부분은 PyPDF2 RectangleObject를 참조하시면 됩니다.


0,1 은 아래 -> 위 방향의 xy좌표

2,3 은 위 -> 아래 방향의 xy좌표 입니다.


쨋든 이렇게 PDF에 워터마크를 삽입하는 코드가 완료되었습니다.


전체 코드는 다음과 같습니다.


# -*- coding:utf-8 -*-

import sys #매개변수를 입력받기 위해 사용
from PIL import Image
from reportlab.pdfgen.canvas import Canvas
from PyPDF2 import PdfFileReader, PdfFileWriter

def ClearWhiteBackground(image):
    #RGBA로 속성 변경
    image = image.convert('RGBA')

    #해당 이미지의 배열 받아오기
    imageData = image.getdata()

    newImageData = []

    for pixel in imageData:
        if pixel[0] > 240 and pixel[1] > 240 and pixel[2] > 240:
            # rgb값이 240,240,240 이상일 경우(흰색에 가까울 경우) 알파값을 0으로 준다
            newImageData.append((0,0,0,0))
        else:
            # 아닐경우 그대로 쓴다
            newImageData.append(pixel)

    #이미지를 덮어 씌움
    image.putdata(newImageData)

    return image

def ImageToPDF(imagePath, pdfPath):
    newCanvas = Canvas(pdfPath, pagesize=Image.open(imagePath,'r').size)

    newCanvas.drawImage(image=imagePath,x=0,y=0, mask='auto')

    newCanvas.save()

def PDFMerge(savePath, pdfPath, watermarkPdfPath):
    # pdf파일 불러오기
    pdfFile = open(pdfPath,'rb')
    pdfReader = PdfFileReader(pdfFile, strict=False)

    # 워터마크 PDF파일 불러오기
    watermarkPdfFile = open(watermarkPdfPath, 'rb')
    watermarkPdf = PdfFileReader(watermarkPdfFile, strict=False).getPage(0)

    pdfWriter = PdfFileWriter()

    #PDF 페이지 수만큼 반복
    for pageNum in range(pdfReader.numPages):

        #페이지를 불러온다
        pageObj = pdfReader.getPage(pageNum)

        #중앙으로 놓기 위해 좌표를 구한다
        x = (pageObj.mediaBox[2] - watermarkPdf.mediaBox[2]) / 2
        y = (pageObj.mediaBox[3] - watermarkPdf.mediaBox[3]) / 2

        # 워터마크페이지와 합친다
        pageObj.mergeTranslatedPage(page2=watermarkPdf, tx=x, ty=y, expand=False)

        #합친걸 저장할 PDF파일에 추가한다
        pdfWriter.addPage(pageObj)

    #저장
    resultFile = open(savePath, 'wb')
    pdfWriter.write(resultFile)

def Test():
    argList = sys.argv

    '''
    매개변수에 두번째는 이미지가 있는 경로, 세번째는 이미지의 이름, 네번째는 PDF파일의 경로가 들어온다
    첫번째는 파일의 경로 고정
    ex) 'C:\\ImageToPDF.py' 'C:\\ImagePath\\' 'sample.jpg' 'testpage.pdf'
    '''

    image = Image.open(argList[1]+argList[2],'r')
    clearImage = ClearWhiteBackground(image)

    clearImage.save(argList[1]+'clearSample.png')

    ImageToPDF(argList[1]+'clearSample.png', argList[1]+'watermarkImage.pdf')

    PDFMerge(argList[1]+'complete.pdf', argList[1]+argList[3], argList[1]+'watermarkImage.pdf')

Test()

ImageToPDF.py



코드를 조금 응용해서 글씨를 써 넣을수도, 로테이션을 줄 수도 있습니다.


그리고 이미지에 투명도를 조금 더 설정해서 글씨 뒤로 보내는것처럼 보이게 할 수도 있습니다


그 부분들은 크게 어렵지 않은 부분들이니 한번 해 보시길 바랍니다.


반응형