ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [python] 파이썬 사진 자르기 / 비율 맞춰서 사진 자르는 프로그램
    파이썬 2022. 7. 26. 01:59
    반응형

    파이썬으로 비율에 맞춰서 사진을 잘라주는 프로그램에 대해 설명해보겠다.

    먼저, 전체 코드는 아래와 같다. (파일은 글 맨 아래에 링크 있습니다.)

    from PIL import Image
    from os import listdir, getcwd
    
    def imageCut(ratio, originDir, cuttedDir):
        for imageName in listdir(originDir):
            print(imageName)
            imageType = imageName[-3:]
            
            if imageType=="png":
                img = Image.open(originDir+'/'+imageName)
    
                # 자를 방향 선택
                if img.width*ratio < img.height:
                    W = img.width
                    H = img.width*ratio
    
                    diff = (img.height-H)/2
                    cuttedImg = img.crop((0,diff,W,H+diff))
                    
                else:
                    print("__"+imageName)
                    W = img.height/ratio
                    H = img.height
    
                    diff = (img.width-W)/2
                    cuttedImg = img.crop((diff,0,W+diff,H))
    
                
                
                if cuttedImg.save(cuttedDir+'/'+imageName[:-4]+'_C.png', "png"):
                    print(imageName,"is cutted successfully.")
                    
            else:
                print("Program need 'png' type file.")
        else: print("All the data in %s was cutted successfully. \n\n"%originDir)
    
    if __name__ == "__main__":
        ratio = 424/620
    
        originDir = getcwd() # current dir
        cuttedDir = getcwd() # current dir
    
        imageCut(ratio, originDir, cuttedDir)

     

     

     

    이후부터는 이 코드들에 대해 자세히 설명해보겠다.

    from PIL import Image
    from os import listdir, getcwd

    이미지를 다루기 위해 Image 모듈을PIL 패키지에서 불러왔고, listdir 및 getcwd 함수를 os 패키지로부터 불러왔다.

     

    전체 함수(imageCut) 코드는 다음과 같다.

    매개변수로 비율인 ratio와 원래 사진 위치(originDir), 잘려진 사진 위치(cuttedDir)를 받는다.

    def imageCut(ratio, originDir, cuttedDir):
        for imageName in listdir(originDir):
            print(imageName)
            imageType = imageName[-3:]
            
            if imageType=="png":
                img = Image.open(originDir+'/'+imageName)
    
                # 자를 방향 선택
                if img.width*ratio < img.height:
                    W = img.width
                    H = img.width*ratio
    
                    diff = (img.height-H)/2
                    cuttedImg = img.crop((0,diff,W,H+diff))
                    
                else:
                    print("__"+imageName)
                    W = img.height/ratio
                    H = img.height
    
                    diff = (img.width-W)/2
                    cuttedImg = img.crop((diff,0,W+diff,H))
    
                
                
                if cuttedImg.save(cuttedDir+'/'+imageName[:-4]+'_C.png', "png"):
                    print(imageName,"is cutted successfully.")
                    
            else:
                print("Program need 'png' type file.")
        else: print("All the data in %s was cutted successfully. \n\n"%originDir)

     

    반응형

     

    아래와 같이, originDir 주소 내의 모든 파일을 불러온다.

    그리고 imageType은 문자열의 맨 뒷 세자리만 불러온다. (맨 뒤 세자리가 png인지 아닌지만 구분하기 위해 간단하게 구현하였다.)

    그 이후, 앞서 언급했던 것처럼 확장자가 png인지 검사한다. 코드를 돌려본 결과, Image 모듈은 jpg를 지원하지 않는 것 같다. (jpg로 저장하려고 했을 때 에러를 발생시킴.) 따라서, png로 된 파일을 다루자.

     

    png가 아닌 파일들을 png로 변환시키기 위하여 사이트를 소개하고자 한다. 

    https://jpg2png.com/ko/

     

    JPEG 파일을 PNG로

    JPG 이미지를 PNG 포맷으로 온라인에서 올바른 압축기법을 사용하여 무료 전환 하세요

    jpg2png.com

    * 하지만 이 사이트에 대한 신뢰도는 확실치 않으므로 사용에 유의한다. (데이터를 따로 저장하는지 등)

     

    이후, 비율에 따라 사진을 자를건데 비율에 맞으면서도 최대한 큰 사이즈로 데이터 손실이 적게 자를 예정이다. 자를 방향을 선택할텐데, 조건문을 보면 "이미지의 가로 * 비율 < 이미지의 세로" 일 때 세로를 자른다. 

    나머지(else)의 경우, "이미지의 가로 >= 이미지의 세로 / 비율" 일 때 가로를 자른다. 자르는 것은 img.crop 메소드를 사용한다. 앞의 두 매개변수는 0에 가깝고, 뒤의 두 변수는 사진의 크기에 맞게 넣어주면 된다. width, height 순서로 넣어준다.

    위를 보면, diff라는 변수를 통해 자를 범위를 양 옆에 똑같이 배분했음을 알 수 있다. 

     

    이후 이름에 _C를 덧붙인 채로 새로운 파일이 형성된다. 형성되는 주소는 cuttedDir 매개변수로 설정해줄 수 있다. 여기서 if문을 쓴 이유는 성공적으로 잘렸을 때 print함수로 알려주기 위함인데, 왠지 모르게 프린트가 안되더라.. 사진을 자르는 작동은 잘 된다.

     

    맨 처음의 if문에 대한 else문이다. 처음에 "이름 맨 뒤 세글자가 png인가?"로 시작하는데, 그것이 아닐 경우 아래와 같다. 

    * 만약 png 구분에서 잦은 오류가 생긴다면, "맨 뒤의 네글자가 .png인가?"로 간단하게 수정해줄 수 있겠다. 

    다른 확장자는 else문을 실행시키게 된다.

     

    아래는 반복문에 대한 else문이다. 반복문이 다 돌면 아래와 같은 문구가 나온다.

     

    __name__ == "__main__"을 통해, Run을 통해 직접적으로 파이썬 파일이 실행될 때에만 작동하도록 설계하였다.

    ratio는 첫번째 사진의 비율을 임의로 넣었고, 프로그램이 작동하면 첫번째 사진의 비율에 모든 사진들의 비율이 맞추어져 잘릴 것이다. 

    getcwd() 함수를 이용하여 현재 디렉토리 주소를 불러왔다. 잘린 후 저장될 이미지의 주소도 동일하게 설정하였다.

    코딩한 imageCut 함수에 ratio, originDir, cuttedDir를 순서대로 매개변수로 넣어주었다.

    작동을 시키면 아래와 같다.

    비포
    에프터

    아주 비슷한 비율로 사진이 잘린것을 확인할 수 있고, png만 골라 작동한 것을 확인할 수 있다.

    파일은 아래 네이버 블로그에서 다운받을 수 있다 

     

    https://blog.naver.com/haim1121/222828803464

     

    [Python] 비율에 맞게 사진 자르는 파이썬 프로그램 / PIL image, os listdir, getcwd

    비율에 맞게 사진을 잘라주는 파이썬 프로그램 파일을 공유하고자 한다. 파일은 png 파일에만 작동한다. 모...

    blog.naver.com

     

     

     

     

     

     


    오류, 질문이 있으면 댓글달아주세요

    구독은 항상 환영입니다 :)


     

    반응형

    댓글

Designed by Tistory.