Python裁剪序列帧空白区域-CutImage

版权声明:转载请联系 https://blog.csdn.net/liyaxin2010/article/details/84196790

Python裁剪序列帧空白区域-CutImage

问题

接上篇:EgreWing带透明Image点击区域测试

思路:读取该序列帧每张图片的区域,计算出可以包住所有图片的外圈范围,在1024*1024的大图基础上裁剪每张图片,生成统一的大小。。单张图片就当做只有一帧的序列帧来处理。如下图:三张序列帧的范围frame1,frame2,frame3,最终导出3张最外圈大小的图片。

代码实现

1、复制图片到输出目录


# 遍历目录封装
def traverse_dirs(dirname, callback, params):
   names = os.listdir(dirname)
   for name in names:
      if name == ".svn" or name == ".git":
         continue;

      subdirname = os.path.join(dirname, name)
      try:
         if os.path.isdir(subdirname):
               traverse_dirs(subdirname, callback, params)
         else:
               callback(subdirname, params)
      except:
         raise;

# 拷贝到输出目录
def copy_files(outpath):
   if not os.path.exists(outpath):
      os.makedirs(outpath)

   filePaths = []; 
   traverse_dirs(dirpath, func_traverse_dirs, filePaths)
   for filepath in filePaths:
      shutil.copy2(filepath, outpath + '/' + os.path.basename(filepath))

2、计算目录下序列帧的四个边界

# 四个边界
def get_cropped_boxes(dirpath, crop_onebyone):
   filePaths = []; 
   traverse_dirs(dirpath, func_traverse_dirs, filePaths)

   x, y, w, h = 2048, 2048, 0, 0

   for filepath in filePaths:
      if is_filter_file(filepath, dirpath): continue

      image = Image.open(filepath)
      image.load()

      imageSize = image.size
      imageBox = image.getbbox()
      
      imageComponents = image.split()

      if len(imageComponents) < 4: continue #don't process images without alpha

      rgbImage = Image.new("RGB", imageSize, (0,0,0))
      rgbImage.paste(image, mask=imageComponents[3])
      croppedBox = rgbImage.getbbox()

      if croppedBox[0] < x: x = croppedBox[0]
      if croppedBox[1] < y: y = croppedBox[1]
      if croppedBox[2] > w: w = croppedBox[2]
      if croppedBox[3] > h: h = croppedBox[3]

3、 处理图片 按照上一步计算出来的边界来裁剪

# crop 裁剪
for filepath in filePaths:
   if is_filter_file(filepath, dirpath): 
      continue

   image = Image.open(filepath)
   image.load()

   imageSize = image.size
   imageBox = image.getbbox()

   imageComponents = image.split()

   if len(imageComponents) < 4: continue #don't process images without alpha

   croppedBox = (x, y, w, h)

   # UI图片非序列帧可以把crop_onebyone设置为True
   if crop_onebyone:
      rgbImage = Image.new("RGB", imageSize, (0,0,0))
      rgbImage.paste(image, mask=imageComponents[3])
      croppedBox = rgbImage.getbbox()
   else:
      print("crop_onebyone == false")

   cropped = image.crop(croppedBox)
   cropped.save(filepath)

4、大小如果超标可以等比缩放

# 限制图片大小
maxsize = (512,512)
def resize_files(outpath):
   filePaths = []; 
   traverse_dirs(outpath, func_traverse_dirs, filePaths);
   for filepath in filePaths:
      if is_filter_file(filepath, outpath): 
         continue
      image = Image.open(filepath)
      image.thumbnail(maxsize, Image.ANTIALIAS)
      image.save(filepath)

其他

  • UI图片这种单张图片可以设置crop_onebyone为True。
  • 执行get_cropped_boxes("./xxx", True)就ok了。

后记

  • 后来想想美术打开.bat或者.py编辑目录有点麻烦,于是查了下python导出exe选择目录去执行的方法,使用Tkinter或者Wxpython实现,下一篇再探讨细节hohoho。。

  • 看到有人实现的单张图片裁剪的,只需要裁剪单张可以这样:
    https://blog.csdn.net/qq_24226819/article/details/73716482

    #!/usr/bin/env python
    # coding: utf-8
    from PIL import Image
    import types
    
    def get(path, i):
        im = Image.open(path, 'r')
        width, height = im.size
        pix = im.load()
        minx = 10000
        miny = 10000
        maxx = -1
        maxy = -1
        for x in range(0, width):
            for y in range(0, height):
                if pix[x, y][3] != 0:
                    if minx > x:
                        minx = x
                    if miny > y:
                        miny = y;
                    if maxx < x:
                        maxx = x
                    if maxy < y:
                        maxy = y;
        print i,minx, miny
        #print maxx, maxy
        cut(path, minx, miny, maxx, maxy)
    def cut(path, minx, miny, maxx, maxy):
        im = Image.open(path)
        box = (minx, miny, maxx, maxy)  # 设定裁剪区域
        region = im.crop(box)  # 裁剪图片,并获取句柄region
        region.save(path, 'png')
    for i in range(1,95):
        path = "D:\\mytest\\cut\\1111\\100"+str(i)+".png"
        get(path, i)
    


参考

猜你喜欢

转载自blog.csdn.net/liyaxin2010/article/details/84196790