2012年3月8日星期四

长图切割 PIL实践

image

趁着之前新浪微博还没有关闭basic auth的时候,在一个图片分享微博上下了很多图。图美则美矣,可惜播放幻灯片时候这种长条图就看上去不大清爽了。

所以打算写个程序把这些图用编程手段自动分离了。

虽然上过图像处理课,但真学得一桶浆糊,脑袋里好像有边界算法这个概念,到底是怎么样的根本就没影了。只能用点笨办法了。

因为水平方向没有多图,现只考虑垂直方向的切割。思路是找出4张图的边界,即垂直方向的5个点,用红笔标出。

垂直分界点的显著特征

  • 其所在水平方向的像素值都是相同的;
  • 垂直分界点所在行与内容图的像素行不同。

从图左上开始查找分界点,根据上述两规则,找到所有分界点。

先安装Python PIL (Python包安装也太ugly了)。

上代码:

import Image

#only check the color in horizontal direction
def isInSameColor(image,y,im_width):
    original_point=image.getpixel((0,y))
    for x in range(1,im_width):
        if(original_point!=image.getpixel((x,y))):
            return False
    return True
       
def IsDiffBetween2Line(image,y1,y2,im_width):
    for x in range(im_width):
        if(image.getpixel((x,y1))!=image.getpixel((x,y2))):
            return True
    return False

def SplitImage(image,im_points,im_width,imFileName):
    filename=imFileName.split('.')[0]
    print filename
    for i in range(len(im_points)-1):       
        region=image.crop([0,im_points[i],im_width,im_points[i+1]])       
        print region.size       
        region.save(filename+'[%d].jpg'%i,'JPEG')
       

if __name__ == '__main__':
    #replace the imFileName with your own photo
    imFileName='7f9e9b4dgw1dk3y3wryrlj.jpg'
    im=Image.open(imFileName)
   
    im_width=im.size[0]
    im_height=im.size[1]
   
    #where to save boundary point in ...
    im_points=[]
   
#    print im_width,im_height
    y0=0
    for y in range(1,im_height):
        if y==im_height-1:break
        if isInSameColor(im,y0,im_width) is True:
            #compare with next line
            if IsDiffBetween2Line(im,y0,y,im_width) is True:
                im_points.append(y0)
        y0=y
   
    #append the last point
    im_points.append(im_height-1)      
    print im_points
   
    SplitImage(im, im_points, im_width, imFileName)
    print "The end!"

 

结果:

image

没有评论:

发表评论