歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 用Python切掉圖片的黑邊

用Python切掉圖片的黑邊

日期:2017/3/1 9:41:59   编辑:Linux編程

手機裡有很多G+裡的截屏,都有一些黑邊。像這樣:

因為原圖片的長寬不一定,導致黑邊的大小不一定。

雖然圖片都是居中的,但是有些圖片是寬比高大,是橫著截圖的,所以這樣的情況是上下左右都可能有黑邊。

於是想到了用python的 PIL庫來進行裁切。

研究了一下,原代碼如下

  1. from PIL import Image
  2. import os
  3. src_folder = "."
  4. tar_folder = "tar"
  5. backup_folder = "backup"
  6. def isCrust(pix):
  7. return sum(pix) < 25
  8. def hCheck(img, y, step = 50):
  9. count = 0
  10. width = img.size[0]
  11. for x in xrange(0, width, step):
  12. if isCrust(img.getpixel((x, y))):
  13. count += 1
  14. if count > width / step / 2:
  15. returnTrue
  16. returnFalse
  17. def vCheck(img, x, step = 50):
  18. count = 0
  19. height = img.size[1]
  20. for y in xrange(0, height, step):
  21. if isCrust(img.getpixel((x, y))):
  22. count += 1
  23. if count > height / step / 2:
  24. returnTrue
  25. returnFalse
  26. def boundaryFinder(img,crust_side,core_side,checker):
  27. ifnot checker(img,crust_side):
  28. return crust_side
  29. if checker(img,core_side):
  30. return core_side
  31. mid = (crust_side + core_side) / 2
  32. while mid != core_side and mid != crust_side:
  33. if checker(img,mid):
  34. crust_side = mid
  35. else:
  36. core_side = mid
  37. mid = (crust_side + core_side) / 2
  38. return core_side
  39. pass
  40. def handleImage(filename,tar):
  41. img = Image.open(os.path.join(src_folder,filename))
  42. if img.mode != "RGB":
  43. img = img.convert("RGB")
  44. width, height = img.size
  45. left = boundaryFinder(img, 0, width/2, vCheck)
  46. right = boundaryFinder(img, width-1, width/2, vCheck)
  47. top = boundaryFinder(img, 0, height/2, hCheck)
  48. bottom = boundaryFinder(img, height-1, width/2, hCheck)
  49. rect = (left,top,right,bottom)
  50. print rect
  51. region = img.crop(rect)
  52. region.save(os.path.join(tar,filename),'PNG')
  53. pass
  54. def folderCheck(foldername):
  55. if foldername:
  56. ifnot os.path.exists(foldername):
  57. os.mkdir(foldername)
  58. print"Info: Folder \"%s\" created" % foldername
  59. elifnot os.path.isdir(foldername):
  60. print"Error: Folder \"%s\" conflict" % foldername
  61. returnFalse
  62. returnTrue
  63. pass
  64. def main():
  65. if folderCheck(tar_folder) and folderCheck(src_folder) and folderCheck(backup_folder):
  66. for filename in os.listdir(src_folder):
  67. if filename.split('.')[-1].upper() in ("JPG","JPEG","PNG","BMP","GIF"):
  68. handleImage(filename,tar_folder)
  69. os.rename(os.path.join(src_folder,filename),os.path.join(backup_folder,filename))
  70. pass
  71. if __name__ == '__main__':
  72. main()
  73. #handleImage('Screenshot_2013-10-13-21-55-14.png','')
    IL import Image
    import os 
    
    src_folder = "."
    tar_folder = "tar"
    backup_folder = "backup"
    
    def isCrust(pix):
        return sum(pix) < 25
    
    def hCheck(img, y, step = 50):
        count = 0
        width = img.size[0]
        for x in xrange(0, width, step):
            if isCrust(img.getpixel((x, y))):
                count += 1
            if count > width / step / 2:
                return True
        return False
    
    def vCheck(img, x, step = 50):
        count = 0
        height = img.size[1]
        for y in xrange(0, height, step):
            if isCrust(img.getpixel((x, y))):
                count += 1
            if count > height / step / 2:
                return True
        return False
    
    def boundaryFinder(img,crust_side,core_side,checker):
        if not checker(img,crust_side):
            return crust_side
        if checker(img,core_side):
            return core_side
    
        mid = (crust_side + core_side) / 2
        while  mid != core_side and mid != crust_side:
            if checker(img,mid):
                crust_side = mid
            else:
                core_side = mid
            mid = (crust_side + core_side) / 2
        return core_side
        pass
    
    def handleImage(filename,tar):
        img = Image.open(os.path.join(src_folder,filename))
        if img.mode != "RGB":
            img = img.convert("RGB")
        width, height = img.size
    
        left = boundaryFinder(img, 0, width/2, vCheck)
        right = boundaryFinder(img, width-1, width/2, vCheck)
        top = boundaryFinder(img, 0, height/2, hCheck)
        bottom = boundaryFinder(img, height-1, width/2, hCheck)
    
        rect = (left,top,right,bottom)
        print rect
        region = img.crop(rect)
        region.save(os.path.join(tar,filename),'PNG')
        pass
    
    def folderCheck(foldername):
        if foldername:
            if not os.path.exists(foldername):
                os.mkdir(foldername) 
                print "Info: Folder \"%s\" created" % foldername
            elif not os.path.isdir(foldername):
                print "Error: Folder \"%s\" conflict" % foldername
                return False
        return True
        pass
    
    def main():
        if folderCheck(tar_folder) and folderCheck(src_folder) and folderCheck(backup_folder):
            for filename in os.listdir(src_folder):
                if filename.split('.')[-1].upper() in ("JPG","JPEG","PNG","BMP","GIF"):
                    handleImage(filename,tar_folder)
                    os.rename(os.path.join(src_folder,filename),os.path.join(backup_folder,filename))
            pass
    
    
    if __name__ == '__main__':
        main()
        #handleImage('Screenshot_2013-10-13-21-55-14.png','')
    

代碼作用是 遍歷當前文件夾下的所有JPG PNG BMP GIF文件,找到內容上下左右的邊距(實際上是內容矩形左上右下���點的坐標),將切出來的圖片保存到目標文件夾中,並備份源文件到備份文件夾中。

boundaryFinder() 函數使用時間復雜度為O(log n)的算法來找到內容的邊緣所在的線(可能是橫線也可能是豎線,取決於checker使用的是哪一個函數)

hCheck() 和 vCheck() 函數分別水平和豎直地對圖片上的某條線,相等間隔(默認50)的取點。如果這些點有一半被認為屬於要被切掉的邊,就會返回true

isCrust()函數判斷點是否屬於要切掉的邊 本例中 RGB三色加起來小於25 就被認為是要黑邊的內容

效果如下:

這個代碼適用於有純色邊的圖片剪切。通過修改isCrust() 函數的算法 可以適用於不同純色邊的裁切

《Python核心編程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm

《Python開發技術詳解》.( 周偉,宗傑).[高清PDF掃描版+隨書視頻+代碼] http://www.linuxidc.com/Linux/2013-11/92693.htm

Python腳本獲取Linux系統信息 http://www.linuxidc.com/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm

Python 的詳細介紹:請點這裡
Python 的下載地址:請點這裡

Copyright © Linux教程網 All Rights Reserved