用Python切掉图片的黑边

本网站用的阿里云ECS,推荐大家用。自己搞个学习研究也不错
手机里有很多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)  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 的下载地址请点这

未经允许不得转载:演道网 » 用Python切掉图片的黑边

赞 (0)
分享到:更多 ()

评论 0

评论前必须登录!

登陆 注册