用python切掉图片的黑边

来源:互联网 发布:网络摄像头内部结构图 编辑:程序博客网 时间:2024/04/27 13:56

手机里有很多G+里的截屏,都有一些黑边。像这样:



因为原图片的长宽不一定,导致黑边的大小不一定。

虽然图片都是居中的,但是有些图片是宽比高大,是横着截图的,所以这样的情况是上下左右都可能有黑边。


于是想到了用python的 PIL库来进行裁切。

研究了一下,原代码如下


from PIL import Imageimport os src_folder = "."tar_folder = "tar"backup_folder = "backup"def isCrust(pix):    return sum(pix) < 25def 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 Falsedef 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 Falsedef 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    passdef 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')    passdef 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    passdef 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))        passif __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() 函数的算法 可以适用于不同纯色边的裁切


0 0
原创粉丝点击