程序运行界面
运行结果对比
前:
后:
详细使用文档 和 应用下载
思路:
1. 我们需要获取所有帧动画的共同外边框 切出来的时候 保证图片大小一样
所以我们需要 通过遍历所有帧 获取他们的公共外边框
2. 我们只需要将所有图片按照这个外边框剪切即可
如果你用的不是Python语言 按照上面那个思路也work
例如c++的话 你只需要将公共外边框内的 像素拷贝到一个新的图片对象中 并保存到本地 即可
源码:
crop.py
# -*- coding:utf-8 -*-
from PIL import Image
import os
import time
import numpy as np # 获取图片像素
from gevent import monkey; monkey.patch_all()
import gevent
from progressBar import ProgressBar
import consoleColorFont
while True:
#文件路径输入
baseurl = input('Input the file root of the animation frame. or enter "exit" quit appliction\n')
if baseurl.lower() == 'exit':
break
baseurl = baseurl.replace('\\', '/')
files = os.listdir(baseurl)
print(f'\n\nconvert path: {baseurl}')
resulturl = baseurl + '_result' #resulturl = baseurl.replace(f'/{os.path.split(baseurl)[1]}', '/result')
print(f'publish path: {resulturl}')
if not os.path.exists(resulturl):
os.makedirs(resulturl)
i = 0
start = time.time() #计时开始
bar = ProgressBar(total = len(files))
tmloaded = 0
maxload = len(files)
consoleColorFont.printYellow(f"\nestimated run time of {round(1.484*maxload,2)} seconds")
imgtable = []
imgtable.append([])
imgtable.append([])
def loadImg(url):
global i
img = Image.open(url)
suffix = os.path.splitext(url)[-1]
save_dir = f'{resulturl}/{i}{suffix}'
i += 1
imgtable[0].append(save_dir)
imgtable[1].append(img)
bar.step()
tasks = []
for file in files:
url = f'{baseurl}/{file}'
tasks.append(gevent.spawn(loadImg,url))
print("\nLoad and cache images:")
gevent.joinall(tasks)
print("cache images finish.\n\n")
x_min = 4096
y_min = 4096
x_max = 0
y_max = 0
_rows = 4096
_cols = 4096
def get_bounding_box(buffer, rows, cols):
global x_max
global x_min
global y_max
global y_min
global tmloaded
for i in range(rows):
for j in range(cols):
if buffer[i, j][3] > 0:
if j < x_min:
x_min = j
if j > x_max:
x_max = j
if i < y_min:
y_min = i
if i > y_max:
y_max = i
bar.step(f"progress: {round(tmloaded/maxload*100,2)}% ")
tmloaded += 1
def run(imgtable):
global _cols
global _rows
tasks = []
bar.count = 0
for i in range(maxload):
buffer = np.array(imgtable[1][i])
rows, cols, dims = buffer.shape
_cols = min(cols, _cols)
_rows = min(rows, _rows)
task = gevent.spawn(get_bounding_box, buffer, rows, cols)
tasks.append(task)
print("Traverse all image pixels Calculate the outer border:")
gevent.joinall(tasks)
print("Outer border statistics are complete.\n\n")
#遍历 所有图片像素; 计算 外边框
run(imgtable)
#形状
_x = max(0, x_min-1)
_y = max(0, y_min-1)
x_ = min(_cols, x_max + 1)
y_ = min(_rows, y_max + 1)
#输出
for i in range(maxload):
imgtable[1][i].crop((_x, _y, x_, y_)).save(imgtable[0][i])
print(f"\n\n===========输出信息=============\nbounding-box {x_min},{y_min} {x_max},{y_max}\ncrop count:{len(files)}\nruntime: {round(time.time()-start,2)}s\n===========输出结束=============")
progressBar.py
import sys, time
from pkg_resources import yield_lines
class ProgressBar:
def __init__(self, count = 0, total = 0, width = 50):
self.count = count
self.total = total
self.width = width
def step(self,r = None):
self.count += 1
sys.stdout.write(' ' * (self.width + 9) + '\r')
sys.stdout.flush()
progress = round( self.width * self.count / self.total )
if r:
sys.stdout.write(r)
else:
sys.stdout.write('{0:3}/{1:3}: '.format(self.count, self.total))
sys.stdout.write('■' * progress + '□' * (self.width - progress) + '\r')
if progress == self.width:
sys.stdout.write('\n')
sys.stdout.flush()
# bar = ProgressBar(total = 10,width=10)
# for i in range(10):
# bar.step()
# time.sleep(1)