글 작성자: HEROHJK

연말에 프로젝트가 생겨서(+게을러져서), Deuluwa 프로젝트를 완성하지 못하고 새해를 맞이하고 있어 상당히 마음이 뒤숭숭합니다.


mac 컴퓨터로 인쇄하는 모든 인쇄물에 워터마크를 삽입해달라는 요구였습니다.


mac은 cups로 인쇄할 때, 모든 출력물을 PDF로 변환 후 인쇄시킵니다.


그래서 해당 프로젝트에서 제가 우선적으로 맡은부분은 PDF에 워터마크를 집어넣는 일이었습니다.


로직자체는 별 어려움이 없지만, 어떻게 집어넣어야 할지가 정말 막막했습니다. 자료를 조금 조사해본 결과, Windows는 spooler를 후킹해서 교체한다고 하는데 mac은 조금 다르게 접근을 해야했기 때문입니다.


결론적으로 해결방법을 찾기는 했는데, 이 이상은 본 주제에 벗어나기때문에 생략하기로 하고, 제가 파이썬을 이용해서 PDF에 워터마크를 삽입하는 로직을 공유하려고 합니다.


수도코드로 생각한 흐름은 아주 간단합니다.


- 원본 PDF파일을 연다

- 이미지를 연다

- 빈 PDF파일을 만든다

- 두개를 합친걸 빈 PDF파일에 추가한다

- 합쳐진 PDF파일을 원본PDF파일로 덮어쓴다

이게 끝입니다(실제로도요)


PDF도 PDF고, 굳이 퍼포먼스까지 생각할 이유도 없어서 제일 편하게 할수있는걸 선택하다보니 파이썬을 선택했습니다.


그리고 mac은 유닉스기반이고, 리눅스와 유닉스는 기본적으로 파이썬 2.X 버전이 내장되어 있기때문에 따로 런타임같은걸 설치해줄 필요도 없습니다(물론 배포할때는 바이너리로 해야겠지만.. 테스트할때요)


구체적인 환경은 다음과 같습니다


Language : Python 2.7

IDE : Pycharm

(뭘로 하든 상관 없습니다. Visual Studio 2017 Community에서도 테스트 했습니다)

Libraries: PyPDF2, pillow, reportlab


자 본론으로 들어가서 먼저 이미지를 PDF로 옮기는 작업을 해 봅시다.


제가 사용할 이미지는 다음과 같습니다.


이건 배경이 흰색으로 처리된 jpg 파일입니다. 이걸 투명처리된 png파일로 변경 후 PDF로 변경할 것 입니다.

(투명처리를 안하면 글씨를 흰 배경이 가려버리기때문)


먼저 이미지 관련 라이브러리인 pillow를 설치 해 줍니다.

(pillow 는 파이썬의 대표 이미지 처리 라이브러리인 P(ython)I(mage)L(ibrary)을 포크하여 현재까지 업데이트하고있는 라이브러리 입니다. PIL이 2009년이후 업데이트가 멈췄기 때문이죠.. pillow대신 opencv도 생각해봤으나, 배보다 배꼽이 더 커질까봐 생략했습니다 ^^;;)


pip install pillow


기본적으로 jpg는 'RGB' 속성을 가지고 있습니다. 이를 투명처리 하려면 'RGBA'색상으로 바꿔줘야 합니다(RGBA는 RGB에서 알파값이 추가되, 투명처리가 가능 합니다)


파일을 불러와, RGBA로 바꾼 후, 흰영역을 투명처리하여 저장하는부분까지의 코드입니다.


# -*- coding:utf-8 -*- import sys #매개변수를 입력받기 위해 사용 from PIL import Image 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 argList = sys.argv ''' 매개변수에 두번째는 이미지가 있는 경로, 세번째는 이미지의 이름이 들어온다 첫번째는 파일의 경로 고정 ex) 'C:\\ImageToPDF.py' 'C:\\ImagePath\\' 'sample.jpg' ''' image = Image.open(argList[1]+argList[2],'r') clearImage = ClearWhiteBackground(image) clearImage.save(argList[1]+'clearSample.png')

ImageToPDF.py



저기서는 아마도 이미지데이터의 배열~ 반복문까지가 궁금하실겁니다.


아주 간단한 선에서 설명을 드리자면, 일반적인 이미지(단색,16색,256색 이런거 말고 RGB를 사용하는)는 픽셀당 3개의 배열을 가지고 있습니다. 각각 R,G,B 세가지의 값입니다. RGBA라면 알파값의 배열도 추가가 되겠죠. 알파값은 0~1사이의 소수이며, 0은 완전한 투명, 1은 완전한불투명을 의미합니다.

따라서 제가 임의대로 설정한 240,240,240 (사실 회색에 가까운 흰색입니다) 이상의 값이면 알파값을 없애버리는식으로, 픽셀이 100*100사이즈로 10000개라면, 10000번을 반복한 행위입니다.


어쨋든 이제, 이 이미지를 PDF로 만들어 봅시다.


관련 라이브러리인 reportlab이 필요합니다.


reportlab은 reportlab이라는 회사에서 만든 PDF 편집 라이브러리인데, PyPDF도 비슷한 기능이긴 하나, 저는 이걸로 빈 PDF파일에 이미지와 문자열을 그렸습니다.

(PyPDF2는 방법을 못찾겠네요.. 혹시라도 도움 주시면 감사하겠습니다)


설치는 pillow와 같습니다.


pip install reportlab


그럼 이제 이미지를 pdf로 변환하는 소스를 살펴보겠습니다.


from reportlab.pdfgen.canvas import Canvas

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()


간단한내용입니다. 이미지와 똑같은 사이즈를 가진 새로운 캔버스를 만들어서,


이미지를 그립니다.


그리고 이미지를 저장하면 끝입니다.


주의점은, 메모리의 이미지는 불러와지지 않기 때문에, 파일의 경로를 입력해야 합니다.


이제 워터마크PDF가 만들어 졌습니다.


여태까지의 작업물입니다.


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

import sys #매개변수를 입력받기 위해 사용
from PIL import Image

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

from reportlab.pdfgen.canvas import Canvas

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 Test():
    argList = sys.argv

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

    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')

Test()



다음포스트에서 이것을 기존 PDF와 합치는 방법을 알아보겠습니다

반응형