340 lines
12 KiB
Python
340 lines
12 KiB
Python
import base64,hashlib,os,shutil
|
|
import math,time,json
|
|
from PIL import Image
|
|
from tinydb import TinyDB, Query
|
|
from common.Constant import pathStr
|
|
|
|
class imageUtils:
|
|
|
|
@classmethod
|
|
def encodeImage(cls,str_en):
|
|
#print("en",str_en)
|
|
enc = base64.b64decode(str_en)
|
|
#print("解密:",enc)
|
|
m = hashlib.md5()
|
|
m.update(enc)
|
|
md5 = m.digest()
|
|
d = md5[-1]
|
|
#print(md5)
|
|
try:
|
|
blocks = d % 10 + 5
|
|
except:
|
|
blocks = 0 %10 + 5
|
|
#print("blocks=",blocks)
|
|
return blocks
|
|
|
|
@classmethod
|
|
def scrambleImage(cls,file_path):
|
|
#检测到未下载完的图像 直接返回None
|
|
if str(file_path).endswith(".downloads"):
|
|
os.remove(file_path)
|
|
return None
|
|
file_str = str(file_path).split("=")
|
|
#10_29.jpg
|
|
base_dir = file_str[0].replace("scramble","")
|
|
base_name = file_str[-1]
|
|
base_fn = base_name.split("_")
|
|
save_name = base_fn[1]
|
|
save_name_delesu = save_name.split(".")[0]
|
|
blocks = int(base_fn[0])
|
|
save_file_path = os.path.join(base_dir,save_name)
|
|
print("sva",save_file_path)
|
|
if os.path.exists(save_file_path):
|
|
print("图片已解密,已跳过:", save_file_path)
|
|
return None
|
|
image_su = str(file_path).split(".")[-1]
|
|
try:
|
|
img = Image.open(file_path)
|
|
except:
|
|
print(f"error Image: {file_path}")
|
|
width = img.width
|
|
height = img.height
|
|
#blocks = cls.encodeImage(enStr)
|
|
print("blocks=",blocks)
|
|
block_height = int(height / blocks)
|
|
block_width = int(width / blocks)
|
|
print("blockHeight=",block_height)
|
|
prefix = str(file_path).split(".")[-1]
|
|
split_path = os.path.join(base_dir,save_name_delesu+"split")
|
|
if image_su == "downloads":
|
|
return None
|
|
is_split = cls.splitimage(file_path,blocks,1,split_path)
|
|
if is_split != None:
|
|
cls.image_compose(split_path,blocks,1,save_file_path,block_height,width)
|
|
else:
|
|
if os.path.exists(split_path):
|
|
shutil.rmtree(split_path)
|
|
if os.path.exists(file_path):
|
|
shutil.move(file_path, save_file_path)
|
|
#完成后清空
|
|
return file_path
|
|
|
|
@classmethod
|
|
def splitimage(cls,src,rownum,colnum,dstpath):
|
|
img=Image.open(src)
|
|
w,h=img.size
|
|
if rownum<= h and colnum<=w:
|
|
s=os.path.split(src)
|
|
if dstpath=='':
|
|
dstpath = s[0]
|
|
if not os.path.exists(dstpath):
|
|
os.makedirs(dstpath)
|
|
fn=s[1].split('.')
|
|
basename=fn[0]
|
|
ext=fn[-1]
|
|
num=0
|
|
rowheight=h//rownum
|
|
colwidth=w//colnum
|
|
for r in range(rownum):
|
|
for c in range(colnum):
|
|
box=(c*colwidth,r*rowheight,(c+1)*colwidth,(r+1)*rowheight)
|
|
count_image = "{:0>3d}".format(num)
|
|
file_path = os.path.join(dstpath,str(count_image)+'.'+ext)
|
|
print("file_path=",file_path)
|
|
img.crop(box).save(file_path)
|
|
num=num+1
|
|
return "成功"
|
|
else:
|
|
print('不数!')
|
|
return None
|
|
|
|
@classmethod
|
|
def image_compose(cls,src,row,column,save_path,image_height,image_width):
|
|
image_size = image_height
|
|
#image_height = 376
|
|
#image_width = 720
|
|
images_format = ['.png','.jpg']
|
|
|
|
#image_names = [name for name in os.listdir(src) for item in images_format if
|
|
# os.path.splitext(name)[1] == item][::-1]
|
|
img_list=os.listdir(src)
|
|
img_list.sort()
|
|
img_list.sort(key=lambda x: int(x[:-4]))
|
|
##文件名按数字排序
|
|
img_nums=len(img_list)
|
|
image_names = []
|
|
for i in range(img_nums):
|
|
img_name=os.path.join(src,img_list[i])
|
|
image_names.append(img_name)
|
|
#使用倒序
|
|
image_names = image_names[::-1]
|
|
# 简单的对于参数的设定和实际图片集的大小进行数量判断
|
|
if len(image_names) < row * column:
|
|
raise ValueError("合成图片的参数和要求的数量不能匹配!")
|
|
|
|
to_image = Image.new('RGB', (column * image_width, row * image_height)) #创建一个新图
|
|
# 循环遍历,把每张图片按顺序粘贴到对应位置上
|
|
for y in range(1, row + 1):
|
|
for x in range(1, column + 1):
|
|
#1 * (row=1 -1) col=1 -1
|
|
image_path = image_names[column * (y - 1) + x - 1]
|
|
print("split_image=",image_path)
|
|
from_image = Image.open(image_path)
|
|
#保持原图片大小
|
|
#.resize(
|
|
# (image_size, image_size),Image.ANTIALIAS)
|
|
to_image.paste(from_image, ((x - 1) * image_size, (y - 1) * image_size))
|
|
from_image.close()
|
|
to_image.save(save_path)
|
|
print("图片合并完成:", save_path)
|
|
shutil.rmtree(src)
|
|
# 保存新图
|
|
|
|
@classmethod
|
|
def getScrambleImage(cls,path):
|
|
scramble_file_cache = cls.scrambleImage(path)
|
|
if scramble_file_cache != None and os.path.exists(scramble_file_cache): os.remove(scramble_file_cache)
|
|
|
|
@classmethod
|
|
def encode_scramble_image(cls,imgpath):
|
|
image = Image.open(imgpath)
|
|
w, h = image.size
|
|
#image.show()
|
|
file_str = str(imgpath).split("=")
|
|
#10_29.jpg
|
|
base_dir = file_str[0].replace("scramble","")
|
|
base_name = file_str[-1]
|
|
base_fn = base_name.split("_")
|
|
save_name = base_fn[1]
|
|
save_name_delesu = save_name.split(".")[0]
|
|
blocks = int(base_fn[0])
|
|
img_type = os.path.basename(imgpath).split('.')[-1]
|
|
save_path = os.path.join(os.path.dirname(imgpath),save_name_delesu+"."+img_type)
|
|
# print(type(aid),type(img_name))
|
|
if blocks:
|
|
s = blocks # 随机值
|
|
# print(s)
|
|
l = h % s # 切割最后多余的值
|
|
box_list = []
|
|
hz = 0
|
|
for i in range(s):
|
|
c = math.floor(h / s)
|
|
g = i * c
|
|
hz += c
|
|
h2 = h - c * (i + 1) - l
|
|
if i == 0:
|
|
c += l;hz += l
|
|
else:
|
|
g += l
|
|
box_list.append((0, h2, w, h - g))
|
|
|
|
# print(box_list,len(box_list))
|
|
item_width = w
|
|
# box_list.reverse() #还原切图可以倒序列表
|
|
# print(box_list, len(box_list))
|
|
newh = 0
|
|
image_list = [image.crop(box) for box in box_list]
|
|
# print(box_list)
|
|
newimage = Image.new("RGB", (w, h))
|
|
for image in image_list:
|
|
# image.show()
|
|
b_w, b_h = image.size
|
|
newimage.paste(image, (0, newh))
|
|
|
|
newh += b_h
|
|
newimage.save(save_path)
|
|
print("解密成功=",save_path)
|
|
if os.path.exists(imgpath):
|
|
os.remove(imgpath)
|
|
print("remove=",imgpath)
|
|
|
|
class fileUtils:
|
|
@classmethod
|
|
def exists(cls,path):
|
|
return os.path.exists(path)
|
|
@classmethod
|
|
def notExists(cls,path):
|
|
return not cls.exists(path)
|
|
|
|
@classmethod
|
|
def size(cls,file_path,unit=None):
|
|
size = 0
|
|
if cls.exists(file_path): size = os.path.getsize(file_path)
|
|
if unit == "kb" or unit == "KB":
|
|
return str(size/1000)+"KB"
|
|
if unit == None:
|
|
return size
|
|
|
|
@classmethod
|
|
def ver_file(cls,file_path,type,min_size=10):
|
|
time.sleep(0.1)
|
|
file_size_unit = cls.size(file_path,unit="kb")
|
|
if type == "image" and int(cls.size(file_path)) > min_size:
|
|
#验证是否是图像
|
|
try:
|
|
img = Image.open(file_path)
|
|
img.verify()
|
|
img.close()
|
|
print(f"{file_path} 类型为type:{type} size: {file_size_unit}")
|
|
return True
|
|
except:
|
|
if os.path.exists(file_path):
|
|
os.remove(file_path)
|
|
print(f"{file_path}已损坏 type:{type} size: {file_size_unit},删除重试中")
|
|
return False
|
|
else:
|
|
print(f"文件小于100b删除中,{file_path} size: {file_size_unit}")
|
|
try:
|
|
os.remove(file_path)
|
|
except Exception as e:
|
|
print(e)
|
|
return False
|
|
|
|
@classmethod
|
|
def dirFilesName(cls,path,type="file",prefix=None):
|
|
result = []
|
|
if cls.exists(path):
|
|
for file_or_dir in os.listdir(path):
|
|
if type == "file" and os.path.isfile(os.path.join(path,file_or_dir)): result.append(file_or_dir)
|
|
if type == "dir" and os.path.isdir(os.path.join(path,file_or_dir)): result.append(file_or_dir)
|
|
return result
|
|
|
|
@classmethod
|
|
def equImages(cls,dir,files,prefix=".jpg"):
|
|
len_count = 0
|
|
file_names = cls.dirFilesName(dir,"file")
|
|
for file in file_names:
|
|
if str(file).endswith(prefix): len_count += 1
|
|
return len_count == len(files)
|
|
|
|
@classmethod
|
|
def remove(cls,path):
|
|
if not os.path.exists(path):
|
|
return None
|
|
try:
|
|
print(f"{path} 删除中...")
|
|
if os.path.isfile(path):
|
|
os.remove(path)
|
|
if os.path.isdir(path):
|
|
shutil.rmtree(path)
|
|
print(f"已删除:{path}")
|
|
return True
|
|
except:
|
|
print(f"删除错误:{path}")
|
|
return False
|
|
|
|
#文件保存
|
|
@classmethod
|
|
def file_save(cls,path,data,mode=None,print_msg=False):
|
|
result = {}
|
|
f = {}
|
|
dir_name = os.path.dirname(path)
|
|
if not os.path.exists(dir_name):
|
|
os.makedirs(dir_name)
|
|
|
|
save_path = os.path.join(path)
|
|
if os.path.exists(save_path):
|
|
os.remove(save_path)
|
|
data = json.dumps(data)
|
|
if mode == None:
|
|
mode = "w+"
|
|
try:
|
|
f = open(save_path, mode, encoding="utf-8")
|
|
f.write(data)
|
|
f.close()
|
|
if print_msg:
|
|
print("data=",data)
|
|
result = path + "文件写入成功"
|
|
except:
|
|
result = path + "文件写入失败"
|
|
print(result)
|
|
return result
|
|
|
|
class dbUtils:
|
|
@classmethod
|
|
def base_path(cls,path):
|
|
base_dir = pathStr.base_db()
|
|
if not os.path.exists(base_dir):
|
|
os.makedirs(base_dir)
|
|
return os.path.join(base_dir,path)
|
|
|
|
@classmethod
|
|
def init_db(cls,db_name=None):
|
|
if db_name != None: db_name = cls.base_path(db_name)+".json"
|
|
else: db_name = "Comics.json"
|
|
return TinyDB(cls.base_path(db_name))
|
|
|
|
@classmethod
|
|
def setComic(cls,name,progress,db_name=None):
|
|
db = cls.init_db(db_name)
|
|
comic = Query()
|
|
if len(db.search(comic.name == name)) == 0: db.insert({"name":name,"progress":progress})
|
|
else: db.update({"progress":progress},comic.name== name)
|
|
|
|
@classmethod
|
|
def query(cls,name,progress=None,db_name=None):
|
|
db = cls.init_db(db_name)
|
|
result = db.search(Query().name == name)
|
|
if progress != None:
|
|
try:
|
|
if len(db.search((Query().name == name) & (Query().progress == progress))) != 0: result = True
|
|
else: result = False
|
|
except Exception as e:
|
|
print(e)
|
|
return result
|
|
|
|
@classmethod
|
|
def remove(cls,name,db_name=None):
|
|
db = cls.init_db(db_name)
|
|
db.remove(Query().name == name)
|